общая память, MPI и системы массового обслуживания

Мое приложение C++ Unix/окон уже параллелизируется с помощью MPI: задание является splitted в CPU N, и каждый блок выполняется параллельно, довольно эффективное, очень хорошее масштабирование скорости, задание сделано правильно.

Но некоторые данные повторяются в каждом процессе, и для технических причин эти данные не могут быть легко splitted по MPI (...). Например:

  • 5 Гбит статических данных, точно та же самая вещь, загруженная для каждого процесса
  • 4 Гбита данных, которые могут быть распределены в MPI, больше центральных процессоров, используются, меньше, эта RAM на ЦП.

На 4 заданиях ЦП это означало бы, по крайней мере, загрузку RAM на 20 ГБ, большая часть 'потраченной впустую' памяти, это ужасно.

Я думаю с помощью общей памяти для сокращения полной нагрузки, "статический" блок был бы загружен только однажды на компьютер.

Так, основной вопрос:

  • Действительно ли там кто-либо - стандартный способ MPI совместно использовать память на узле? Некоторое легко доступное + свободная библиотека?

    • В противном случае я использовал бы boost.interprocess и используйте вызовы MPI для распределения локальных идентификаторов общей памяти.
    • Общая память была бы считана "локальным ведущим устройством" на каждом узле и совместно использована только для чтения. Никакая потребность в любом виде семафора/синхронизации, потому что это изменение привычки.
  • Какой-либо хит производительности или конкретные вопросы для опасаний?

    • (Там привычка быть любыми "строками" или чрезмерно странными структурами данных, все может быть понижено до массивов и указателей структуры),
  • Задание будет выполняться в PBS (или SGE), система массового обслуживания, в случае процесса грязный выход, интересно, будут ли они очистка определенная для узла общая память.

20
задан Blklight 26 December 2009 в 18:28
поделиться

7 ответов

Одним из все более распространенных подходов в High Performance Computing (HPC) являются гибридные MPI/OpenMP программы. Т.е. у вас есть N MPI-процессов, и каждый MPI-процесс имеет M-потоков. Этот подход хорошо подходит для кластеров, состоящих из многопроцессорных узлов с общей памятью.

Изменение такой иерархической схемы распараллеливания, очевидно, требует некоторых более или менее инвазивных изменений, OTOH, при правильном выполнении, может повысить производительность и масштабируемость кода, а также снизить потребление памяти для реплицируемых данных.

В зависимости от реализации MPI, вы можете быть в состоянии, а можете и не быть в состоянии выполнять вызовы MPI из всех потоков. Это указано в аргументах required и provided для функции MPI_Init_Thread(), которые необходимо вызывать вместо MPI_Init(). Возможными значениями являются

{ MPI_THREAD_SINGLE}
    Only one thread will execute. 
{ MPI_THREAD_FUNNELED}
    The process may be multi-threaded, but only the main thread will make MPI calls (all MPI calls are ``funneled'' to the main thread). 
{ MPI_THREAD_SERIALIZED}
    The process may be multi-threaded, and multiple threads may make MPI calls, but only one at a time: MPI calls are not made concurrently from two distinct threads (all MPI calls are ``serialized''). 
{ MPI_THREAD_MULTIPLE}
    Multiple threads may call MPI, with no restrictions. 

По моему опыту, современные реализации MPI, такие как Open MPI, поддерживают наиболее гибкую MPI_THREAD_MULTIPLE. Если вы используете старые библиотеки MPI или какую-то специализированную архитектуру, то вам может быть хуже.

Конечно, вам не нужно выполнять потоковую работу с OpenMP, это просто самый популярный вариант в HPC. Для этого можно использовать, например, библиотеку Boost threads, библиотеку Intel TBB или прямые pthreads или windows threads

.
8
ответ дан 30 November 2019 в 01:18
поделиться

С MPI-2 вы получаете RMA (удаленный доступ к памяти) через такие функции, как MPI_Put и MPI_Get. Использование этих функций, если ваша установка MPI поддерживает их, безусловно, поможет вам снизить общее потребление памяти вашей программой. Стоит добавить сложность в кодировании, но это часть удовольствия от параллельного программирования. И опять же, это держит вас в области MPI.

.
2
ответ дан 30 November 2019 в 01:18
поделиться

У меня было несколько проектов с MPI в SHUT.

Как я знаю, есть много способов распространять проблему, используя MPI, может быть, вы сможете найти другое решение, которое не требует совместного использования памяти, в моем проекте решалось уравнение 7,000,000 и переменная 7,000,000

, если вы сможете объяснить вашу проблему, я постараюсь вам помочь

.
0
ответ дан 30 November 2019 в 01:18
поделиться

Я не работал с MPI, но если это похоже на другие IPC библиотеки, которые я видел, что скрывают, находятся ли другие потоки/процессы/что-либо на той же или другой машине, то это не сможет гарантировать общий доступ к памяти. Да, он может работать с разделяемой памятью между двумя узлами на одной машине, если эта машина сама предоставляет разделяемую память. Но пытаться совместно использовать память между узлами на разных машинах будет в лучшем случае очень сложно, из-за сложных проблем с когерентностью. Я бы ожидал, что это будет просто нереализованно.

Во всей практичности, если вам нужно совместно использовать память между узлами, лучше всего делать это за пределами MPI. Я не думаю, что вам нужно использовать boost. interprocess-стиль разделяемой памяти, т.к. вы не описываете ситуацию, когда различные узлы вносят мелкие изменения в разделяемую память; она либо доступна только для чтения, либо разбита на разделы.

Ответы Джона и Деуса рассказывают о том, как отобразить в файле, что определённо нужно для 5 Гб (gigabit?) статических данных. Данные на каждую центральную процессорную установку звучат одинаково, и вам просто нужно послать сообщение каждому узлу, говоря ему, какую часть файла он должен захватить. Операционная система должна позаботиться о преобразовании виртуальной памяти в физическую в файлах.

Что касается очистки...? Я бы предположил, что она не делает никакой очистки разделяемой памяти, но файлы mmaped должны быть очищены, так как при очистке процесса файлы закрываются (что должно освободить их отображение в памяти). Понятия не имею, какие предупреждения имеются в CreateFileMapping и т.д.

Актуальная "разделяемая память" (т.е. boost.interprocess) не очищается при завершении процесса. Если возможно, я бы порекомендовал попробовать убить процесс и посмотреть, что осталось.

.
7
ответ дан 30 November 2019 в 01:18
поделиться
-

Я мало что знаю об unix, и я не знаю, что такое MPI. Но в Windows то, что вы описываете, точно совпадает с объектом отображения файлов.

Если эти данные вложены в вашу .EXE или загружаемую ею .DLL, то они будут автоматически распределены между всеми процессами. Утечка данных из вашего процесса, даже в результате сбоя, не приведет к утечкам или невыпущенным блокировкам ваших данных. Однако 9Гб .dll звучит немного сомнительно. Поэтому, вероятно, это не сработает для вас.

Однако, вы можете поместить ваши данные в файл, затем CreateFileMapping и MapViewOfFile на нем. Карта может быть считана только для чтения, и вы можете поместить все или часть файла в память. Все процессы будут разделять страницы, которые отображаются одинаково, как и базовый объект CreateFileMapping. Хорошей практикой является закрытие представлений unmap и закрытие дескрипторов, но если вы этого не сделаете, операционная система сделает это за вас в режиме просмотра.

Обратите внимание, что если вы не используете x64, вы не сможете отобразить 5Гб файл в одном виде (или даже 2Гб файл, 1Гб может сработать). Но учитывая, что вы говорите о том, что это уже работает, я предполагаю, что вы уже только x64.

.
0
ответ дан 30 November 2019 в 01:18
поделиться

Если Вы храните свои статические данные в файле, Вы можете использовать mmap на unix для получения случайного доступа к данным. Данные будут вызываться по мере и когда Вам понадобится доступ к определённому битовому элементу данных. Всё, что вам нужно будет сделать, это наложить любые бинарные структуры на данные файла. Это unix-эквивалент описанных выше CreateFileMapping и MapViewOfFile.

Кстати, glibc использует mmap при вызове malloc для запроса более одной страницы данных.

.
0
ответ дан 30 November 2019 в 01:18
поделиться

Я столкнулся с этой проблемой в малой степени, когда использовал MPI несколько лет назад.

Я не уверен, что SGE понимает файлы mapped памяти. Если вы распространяетесь против beowulf cluster, я подозреваю, что у вас будут проблемы с когерентностью. Не могли бы вы немного обсудить вашу многопроцессорную архитектуру?

Мой черновой подход будет заключаться в настройке архитектуры, где каждая часть данных принадлежит определенному процессору. Там было бы два потока: один поток был бы MPI двусторонним и один поток для вычисления результата. Обратите внимание, что MPI и потоки не всегда хорошо играют вместе

.
0
ответ дан 30 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: