Гарантия безопасности для чередующихся MPI Isend / Recv

В связанный вопрос Я узнал, что выполнение request = Isend(...); Recv(...); request.Wait(); является не гарантированно работать, как Isend может ничего не делать, пока request.Wait()отсюда тупик Recv(...) (см. оригинальный вопрос для деталей).

Но что если Isend() / Wait() выполняется в другом потоке, чем Recv? Меня сейчас напрямую не интересуют гарантии безопасности по стандарту. Это связано с тем, что стандарт утверждает безопасность потоков, только если Init_thread Метод вызывается и возвращает правильный уровень. С моей конфигурацией openMPI это не так. Однако я не вижу причины, по которой реализация фактически ограничивает вызовы только из потока, который вызвал Init_thread (фактическое сравнение для идентификатора потока будет необходимо). Я рассуждаю так: если я сериализую все посылки и все записи, mpi никогда не сможет заметить, что я использую более одного потока.

Итак, мой упрощенный код такой:

#include <cassert>
#include <thread>
#include "mpi.h"
void send(int rank, int& item)
{
MPI::Request request = MPI::COMM_WORLD.Isend(&item, sizeof(int), MPI::BYTE, rank, 0);
request.Wait();
}

void recv(int rank, int& item)
{
MPI::COMM_WORLD.Recv(&item, sizeof(int), MPI::BYTE, rank, 0);
}

int main()
{
MPI::Init();
int ns[] = {-1, -1};
int rank = MPI::COMM_WORLD.Get_rank();
ns[rank] = rank;
auto t_0 = std::thread(send, 1 - rank, std::ref(ns[rank])); // send rank to partner (i.e. 1 - rank)
auto t_1 = std::thread(recv, 1 - rank, std::ref(ns[1 - rank])); // receive partner rank from partner
t_0.join();
t_1.join();
assert( ns[0] == 0 );
assert( ns[1] == 1 );
MPI::Finalize();
}

Объяснение кода: два потока выполняются на каждом процессоре. Один пытается Isend некоторые данные для партнера и ждет, пока это не будет сделано, другой получает некоторые данные от партнера.

Вопрос: Могу ли я с уверенностью предположить, что большинство реализаций MPI не засоряют этот кусок кода?

(Отказ от ответственности: этот фрагмент кода не предназначен для того, чтобы быть исключительным или особенно красивым. Он предназначен только для демонстрационных целей)

0

Решение

Вопрос: Могу ли я с уверенностью предположить, что большинство реализаций MPI не засоряют этот кусок кода?

На практике — да, если вы добавляете синхронизацию (чего нет в вашем коде); в теории — нет. Хотя возможно, что некоторые реализации допускают сериализованные вызовы из разных потоков на MPI_THREAD_SINGLE уровень (с таким открытым Open MPI — см. Вот), стандарт MPI требует, чтобы библиотека была инициализирована на MPI_THREAD_SERIALIZED уровень. Если вы намереваетесь сделать ваше программное обеспечение переносимым и иметь возможность компилировать и корректно работать с другими реализациями MPI, вам не следует полагаться на какое-то конкретное поведение Open MPI.

Тем не менее, Open MPI может быть настроен для поддержки многопоточности (MPI_THREAD_MULTIPLE) когда библиотека построена. По умолчанию поддержка MT не включено по причинам производительности. Вы можете проверить состояние вашей конкретной установки, используя ompi_info:

$ ompi_info | grep MPI_THREAD_MULTIPLE
Thread support: poxis (MPI_THREAD_MULTIPLE: no, progress: no)
^^^^^^^^^^^^^^^^^^^^^^^

Эта конкретная сборка не поддерживает многопоточность и всегда возвращает MPI_THREAD_SINGLE в provided выходной аргумент MPI_Init_thread,

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector