О параллельных вычислениях на C++ и Java
Когда в Engitex появилась утилита JMP, основной идеей было облегчить создание SPMD (single program, multiple data) и MPMD (multiple programs, multiple data) параллельных программ на Яве. Также было важно иметь возможность явно задавать политику распределения нагрузки как в рамках одной машины («ноды») в кластере, так и между несколькими машинами.
Почему Java?
Это лишь некоторые из "фич", выигрышно отличающие Яву от компилируемого в машинный код C++ и некоторых других языков:
• Модульная структура ПО, при которой нет необходимости полной перекомпиляции программы при изменении кода в каком-то классе.
• Широкий набор бесплатных прикладных библиотек для веб, анализа данных, создания GUI, итд.
• Простая в использовании встроенная многопоточность (multhithreading).
• Встроенный продвинутый протокол коммуникации RMI между Ява-программами на разных машинах.
Все это подсказывает, что было бы актуально иметь утилиты для создания распределенных приложений и распределения нагрузки на Яве.
Что в C++?
Хотя ресурсоемкие программы для расчетов, в том числе с параллелизмом на кластере или суперкомпьютере, традиционно создаются на C++, готовой утилиты для создания распределенной архитектуры на C++ нет. Однако современный софт (в том числе enterprise, например, для оптимизации производства) все же больше про SPMD/MPMD параллелизм между несколькими машинами, т.е. "P процессов на Q нодах".
OpenMP - одна из стандартных утилит для компиляции программ с параллелизмом на локальной машине по типу "N нитей на 1 ноде". Ключевая функция OpenMP - простое распараллеливание цикла for. Распределение нагрузки во время исполнения программы происходит по "усмотрению" ОС.
Стандарт MPI облегчает создание распределенных между нодами программ. Библиотеки Microsoft MPI и OpenMPI - распространенные реализации стандарта.
JMP
JMP использует доступный в Яве RMI для общения между как локальными, так и удаленными (на других нодах) Ява-машинами. По сути JMP содержит функционал OpenMP для распараллеливания на 1 ноде (локально) и функционал MPI для распараллеливания между нодами, а также позволяет явно задавать политику распределения нагрузки. Такая утилита по типу "все включено" особенно удобна для реализации микросервисных и распределенных архитектур.
Приведем простой пример запуска процесса на удаленной ноде с помощью JMP. Положим, хотим выполнить сложное вычисление в объекте heavyCalculationTask. JMP автоматически будет использовать заданную политику распределения нагрузки на удаленной ноде: