Вопросы о неблокирующих деталях MPI на основе стандарта

Поэтому совсем недавно я разрабатывал некоторые асинхронные алгоритмы в своих исследованиях. Я проводил несколько параллельных исследований производительности и подозревал, что неправильно понимаю некоторые детали различных неблокирующих функций MPI.

Я видел несколько проницательных сообщений здесь, а именно:

Есть несколько вещей, в которых я не уверен или просто хочу прояснить, связанные с работой с неблокирующими функциями, которые, я думаю, помогут мне потенциально повысить производительность моего текущего программного обеспечения.

Из части Неблокирующая связь стандарта MPI 3.0:

A nonblocking send start call initiates the send operation, but does not complete it. The send start call can return before the message was copied out of the send buffer. A separate send complete call is needed to complete the communication, i.e., to verify that the data has been copied out of the send buffer. With suitable hardware, the transfer of data out of the sender memory may proceed concurrently with computations done at the sender after the send was initiated and before it completed.

...

If the send mode is standard then the send-complete call may return before a matching receive is posted, if the message is buffered. On the other hand, the receive-complete may not complete until a matching receive is posted, and the message was copied into the receive buffer.

Итак, в качестве первого набора вопросов о MPI_Isend (и аналогично MPI_Irecv), кажется, что для обеспечения завершения неблокирующей отправки мне нужно использовать какой-то механизм для чек об оплате, чтобы он был завершен, потому что в худшем случае будет может нет. подходящее оборудование для одновременной передачи данных, верно? Так что, если я никогда не использую что-то вроде MPI_Test или MPI_Wait после неблокирующей отправки, MPI_Isend может никогда не получить свое сообщение, верно?

Этот вопрос относится к некоторым из моих работ, потому что я отправляю сообщения через MPI_Isend и на самом деле не проверяю полноту, пока не получу ожидаемое ответное сообщение, потому что я хочу избежать накладных расходов на вызовы MPI_Test. Хотя этот подход работает, судя по моему чтению, он кажется ошибочным.

Кроме того, во втором абзаце говорится, что для стандартной неблокирующей отправки MPI_Isend он может нет даже начинает отправлять любые свои данные до тех пор, пока процесс назначения не вызовет соответствующий прием. Учитывая доступность MPI_Probe/MPI_Iprobe, означает ли это, что вызов MPI_Isendпо меньшей мере отправит некоторые предварительные метаданные сообщения, такие как размер, источник и тег, чтобы функции проверки в целевом процессе могли знать, что сообщение хочет быть отправлено туда, и поэтому процесс назначения может фактически опубликовать соответствующее получение?

В связи с этим вопрос о зонде. В разделе Зондировать и отменить стандарт говорит, что

MPI_IPROBE(source, tag, comm, flag, status) returns flag = true if there is a message that can be received and that matches the pattern specifed by the arguments source, tag, and comm. The call matches the same message that would have been received by a call to MPI_RECV(..., source, tag, comm, status) executed at the same point in the program, and returns in status the same value that would have been returned by MPI_RECV(). Otherwise, the call returns flag = false, and leaves status undefined.

Исходя из приведенного выше отрывка, становится ясно, что проверка сообщит вам, есть ли доступное сообщение, которое вы можете получить, соответствующее указанным source, tag и comm. Мой вопрос: должны ли вы предполагать, что данные для соответствующей отправки из успешного зондирования еще не были переданы?

Теперь, после прочтения стандарта, мне кажется разумным, что действительно сообщение, известное зонду, не обязательно должно быть сообщением, которое фактически полностью получено локальным процессом. Учитывая предыдущие сведения о стандартной неблокирующей отправке, кажется, что вам нужно опубликовать получение после выполнения проверки, чтобы гарантировать завершение исходной неблокирующей стандартной отправки, потому что могут быть случаи, когда источник отправляет большое сообщение что MPI не хочет копировать в какой-то внутренний буфер, верно? И в любом случае, кажется, что публикация получения после проверки — это то, как вы гарантируете, что вы действительно получите полные данные из соответствующей отправки для отправки. Это правильно?

Этот последний вопрос относится к одному экземпляру в моем коде, где я выполняю вызов MPI_Iprobe, и если это удается, я выполняю вызов MPI_Recv, чтобы получить сообщение. Тем не менее, я думаю, что сейчас это может быть проблематично, потому что я думал, что если зонд увенчается успехом, это означает, что он уже получил все сообщение. Это означало, что MPI_Recv будет работать быстро, так как полное сообщение уже где-то в локальной памяти. Однако теперь я чувствую, что это было неверное предположение, и некоторые разъяснения были бы полезны.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
470
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Стандарт MPI не требует наличия потока выполнения. Это означает, что MPI_Isend() может вообще ничего не делать, пока общение не будет продолжено. Прогресс происходит под капотом большинства подпрограмм MPI, MPI_Test(), MPI_Wait() и MPI_Probe() являются наиболее очевидными.

Боюсь, вы смешиваете прогресс и синхронную отправку (например, MPI_Ssend()).

MPI_Probe() — это локальная операция, это означает, что она не будет связываться с отправителем и спрашивать, было ли что-то отправлено, или продвигать это.

Что касается производительности, вы должны, насколько это возможно, избегать неожиданных сообщений, это означает, что получение должно быть отправлено на одном конце до того, как сообщение будет отправлено на другом конце.

Здесь существует компромисс между производительностью и переносимостью:

  • если вы хотите написать переносимый код, вы не можете предполагать, что существует поток выполнения MPI
  • если вы хотите оптимизировать свое приложение в данной системе, вам следует попробовать библиотеку MPI, которая реализует поток выполнения в используемом вами межсоединении.

Имейте в виду, что большинство реализаций MPI (читайте, что это не предусмотрено стандартом MPI, и вы не должны полагаться на него) отправляют небольшие сообщения в активном режиме. Это означает, что MPI_Send(), скорее всего, вернется немедленно, если сообщение достаточно маленькое (а достаточно маленькое зависит, среди прочего, от вашей реализации MPI, от того, как она настроена или от того, какое межсоединение используется).

Большое спасибо за ваш ответ, я думаю, что вы дали мне несколько полезных ответов на мои вопросы. Можете ли вы объяснить, что вы имели в виду, когда сказали, что я смешиваю концепции прогресса с синхронной отправкой? И зондирование в основном делается для того, чтобы справиться с ситуацией, когда вы знаете, что можете получить неожиданные сообщения, верно? В противном случае вы, как правило, знали бы, что нужно просто опубликовать соответствующий набор сообщений без необходимости проверки, верно?

spektr 01.07.2019 03:52

если вы не знаете максимальный размер получаемого сообщения, вы можете использовать MPI_Probe(), выделить буфер нужного размера, а затем MPI_Recv(). В противном случае вы можете рассмотреть возможность пересмотра своего алгоритма. MPI_Send() возвращается, когда буфер отправки можно использовать повторно, и нет гарантии, что соответствующий прием был отправлен или что сообщение покинуло хост. MPI_Ssend() возвращает, когда буфер отправки может быть повторно использован а также, отправка сообщения была начата из-за соответствующего приема.

Gilles Gouaillardet 01.07.2019 04:01

Спасибо за всю эту информацию, она оказалась весьма полезной. Пример моей ситуации: я построил распределенный контейнер, аналогичный массиву. Этот контейнер распределяет данные по коммуникатору процессов и позволяет, например, запрашивать данные внутри этого контейнера по некоторому индексу. Чаще всего индекс приводит к запросу данных из другого процесса. Насколько я понимаю, каждый процесс должен проверять, просто чтобы узнать, не запрашивает ли какой-либо другой процесс доступ к некоторым данным, поскольку он не может предсказать это заранее. Видите ли вы альтернативу этому подходу?

spektr 01.07.2019 04:25
MPI хорошо подходит для отправки/получения или коллективных операций. Обычно вы бы MPI_Scatter() данные и MPI_Gather() результаты. Согласно вашему описанию, вы можете рассмотреть односторонние операции (MPI_Put() и MPI_Get()) или альтернативы без MPI, такие как PGAS (OpenSHMEM, ко-массивы Fortran, ...). MPI, как правило, не подходит для обработки событий.
Gilles Gouaillardet 01.07.2019 04:41

Возможно, мне придется взглянуть на односторонние операции, чтобы увидеть, смогу ли я заставить что-то подобное работать в моей ситуации, но ваше последнее утверждение определенно заставляет меня задуматься, будет ли MPI достаточно хорош с точки зрения производительности. Большое спасибо за ваши идеи и мысли!

spektr 01.07.2019 04:46

Ответ правильный и хороший, но я чувствую, что некоторые моменты немного неясны. Хотя MPI не требует прогресса нить, он делает гарантировать прогресс (в конце концов). Конечно, вам не нужна программа, работающая только после долгой задержки, потому что вызов MPI не выполняется. Но приятно знать, что вам не нужно завершать асинхронную отправку, чтобы добиться прогресса в этой отправке. Для второй части гарантия прогресса (для отправки) на самом деле зависит от "соответствующий прием был запущен". Таким образом, поскольку MPI_Probe не запускает прием, это не гарантирует прогресс.

Zulan 01.07.2019 13:03

@Zulan спасибо за ваши дальнейшие комментарии, особенно за ваш первый вопрос о прогрессе!

spektr 01.07.2019 18:36

Другие вопросы по теме