В тредо-безопасной реализации, процесс MPI - процесс, который может быть многопоточным. Каждый тред может производить вызовы MPI; однако, треды адресуемы не отдельно: ранг в посылающем или принимающем вызове идентифицирует процесс, а не тред. Сообщение, посланное процессу может быть получено любым тредом в этом процессе.
Объяснение: Эта модель соответствует модели межпроцессорной связи POSIX: факт, что процесс является многопоточным, а не однопоточным, не затрагивает внешний интерфейс этого процесса. Реализации MPI, где MPI ``процессы'' - треды POSIX внутри одного процесса POSIX, не являются тредо-безопасными по этому определению (действительно, их ``процессы'' - однопоточны). []
Совет пользователям: Ответственность пользователя - предотвратить гонки, когда треды в пределах того же самого приложения посылают противоречивые вызовы связи. Пользователь может удостовериться, что два треда в одном и том же процессе не будут выдавать противоречивые вызовы связи, используя различные коммуникаторы в каждом треде. []
Два основных требования для тредо-безопасной реализации перечислены ниже.
Пример 8.3 Процесс 0 состоит из двух тредов. Первый тред выполняет
блокирующий вызов послать MPI_Send(buff1, count, type, 0, 0, comm)
,
принимая во внимание, что второй тред выполняет блокирующий вызов
получить MPI_Recv(buff2, count, type, 0, 0, comm, &status)
. То есть
первый тред посылает сообщение, которое получено вторым тредом. Эта связь
должна всегда достигнуть цели. Согласно первому требованию, выполнение
будет соответствовать некоторому чередованию из двух вызовов. Согласно
второму требованию, вызов MPI может только блокировать вызывающий
тред и не должен предотвращать продвижение другого треда. Если
посылающий вызов произошел перед получающим вызовом, то посылающий
тред может блокировать, но это не будет предотвращать получающий тред от
выполнения. Таким образом, получающий вызов произойдет. Как только оба
вызова происходят, связь допускается, и оба вызова завершатся. С другой
стороны, однопоточный процесс, который передает послать, сопровождается
соответствующим получить, может блокироваться. Требование продвижения для
многопоточных реализаций более сильное, поскольку блокированный вызов не
может предотвращать продвижение других тредов.
Совет разработчикам:
Вызовы MPI могут быть сделаны тредо-безопасными, выполняясь
только по одному, например, защищая код MPI одной процессо-глобальной
блокировкой. Однако, блокированные операции не могут проводить блокировку,
поскольку это предотвратило бы продвижение других тредов в процессе.
Блокировка проводится только на время локально-атомарной завершающей
подоперации типа регистрации посылающего или завершения посылающего, и
выполняется между ними. Более тонкие блокировки могут обеспечить большее
параллелизма, за счет высоких накладных расходов блокировки. Параллелизм
может также быть достигнут при наличии части протокола MPI,
выполненного отдельными тредами сервера. []