Следующая функция может использоваться, чтобы инициализировать MPI и
инициализировать среду треда MPI, вместо MPI_INIT
.
MPI_INIT_THREAD(required, provided)
IN | required |
желательный уровень поддержки треда (целое число) | |
OUT | provided |
назначенный уровень поддержки треда (целое число) |
int MPI_Init_thread(int *argc, char ***argv, int required,
int *provided)
MPI_INIT_THREAD (REQUIRED, PROVIDED, IERRDR)
INTEGER REQUIRED, PROVIDED, IERROR
int MPI::Init_thread(int& argc, char**& argv, int required)
int MPI::Init_thread(int required)
Совет пользователям:
В Си и С++ передача argc
и argv
необязательно. В
Си это выполнено передачей соответствующего нулевого указателя. В С++
это выполнено с двумя отдельными привязками, чтобы охватить эти два случая. Это
похоже на MPI_INIT
, обсужденный в разделе 4.2.
Этот вызов инициализирует MPI таким же образом, как и вызов
MPI_INIT
. Кроме того, он инициализирует среду треда. Аргумент
required
используется, чтобы определить желательный уровень поддержки
треда. Возможные значения поддержки треда перечислены в порядке
увеличения.
MPI_THREAD_SINGLE
Выполнится только один тред.
MPI_THREAD_FUNNELED
Процесс может быть многопоточным, но
только основной тред будет делать вызовы MPI (все вызовы MPI
``направляются'' к основному треду). Основной тред - тот, который
инициализирует и завершает MPI.
MPI_THREAD_SERIALIZED
Процесс может быть многопоточным, и
многочисленные треды могут делать вызовы MPI, но только по одному:
вызовы MPI не делаются одновременно из двух разных тредов одного и
того же процесса (все вызовы MPI ``последовательны'').
MPI_THREAD_MULTIPLE
Многочисленные треды могут вызывать
MPI без ограничений.
Эти значения последовательны; то есть
MPI_THREAD_SINGLE < MPI_THREAD_FUNNELED < MPI_THREAD_SERIALIZED < MPI_THREAD_MULTIPLE
.
Различные процессы в MPI_COMM_WORLD
могут требовать различных
уровней поддержки треда.
Вызов возвращает в provided
информацию о фактическом уровне
поддержки треда, который будет обеспечен MPI. Он может быть одним из
четырех значений, перечисленных выше.
Уровни поддержки треда, которые может обеспечить MPI_INIT_THREAD
, будут
зависеть от реализации, и могут зависеть от информации, назначенной
пользователем перед запуском программы на выполнение (например, с аргументами
mpiexec
). Если возможно, вызов возвратит
provided = required
. В случае неудачи вызов возвратит наименее
поддерживаемый уровень
такой, что provided > required
(таким образом, обеспечение более сильного
уровня поддержки, чем требуемого пользователем). Наконец, если требование
пользователя не может быть удовлетворено, то вызов возвратит в provided
наиболее поддерживаемый уровень.
тредо-безопасная реализация MPI будет способна возвратить
provided=MPI_THREAD_MULTIPLE
. Такая реализация может всегда
возвращать provided = MPI_THREAD_MULTIPLE
, независимо от
значения required
. В другом экстремальном значении, библиотека
MPI, которая не тредо-безопасна, может всегда возвращать
provided = MPI_THREAD_SINGLE
, независимо от значения required
.
Вызов MPI_INIT
имеет такой же эффект, как и вызов
MPI_INIT_THREAD
с
required = MPI_THREAD_SINGLE
.
Производители могут обеспечивать (в зависимости от реализации), и определять
уровни поддержки треда, доступные, когда начата программа MPI. Это
затронет результат вызовов MPI_INIT
и
MPI_INIT_THREAD
. Предположим, например, что программа MPI
была начата так, чтобы был доступен только MPI_THREAD_MULTIPLE
.
Тогда MPI_INIT_THREAD
возвратит
provided = MPI_THREAD_MULTIPLE
,
независимо от значения required
; вызов к
MPI_INIT
также инициализирует уровень поддержки MPI треда
MPI_THREAD_MULTIPLE
. Предположим, с другой стороны, что
программа MPI была начата так, чтобы все четыре уровня поддержки треда
были доступны. Тогда, вызов к MPI_INIT_THREAD
возвратит
provided = required
; с другой стороны, вызов к MPI_INIT
инициализирует уровень поддержки MPI треда
MPI_THREAD_SINGLE
.
Совет пользователям: Пользователи должны требовать самого низкого уровня поддержки треда, который является совместимым с их кодом. Это оставляет больше свободы для оптимизаций реализацией MPI. []
Объяснение: Различные оптимизация возможны, когда код MPI выполнен однопоточным, или выполнен на множественных тредах, но не одновременно: взаимный код исключения может быть опущен. Кроме того, если выполняется только один тред, то библиотека MPI может использовать библиотечные функции, которые не тредо-безопасны, без того, чтобы рисковать конфликтами с тредами пользователя. Также модель одного треда связи со множественными тредами вычисления хорошо удовлетворяют многим приложениям. Например, если код процесса - последовательная программа ФОРТРАН/Си/С++ с вызовами MPI, которая была распараллелена компилятором для выполнения на узле SMP, в кластере SMP, тогда вычисление процесса многопоточно, но вызовы MPI вероятно выполнятся на одном треде.
Оформление приспосабливает статическую спецификацию уровня поддержки
треда (например, с аргументами mpiexec
), для сред, которые требуют
статической привязки библиотек, и для совместимости для текущих
многопоточных кодов MPI. []
Совет разработчикам:
Если provided
не MPI_THREAD_SINGLE
, тогда библиотека
MPI не должна использовать ФОРТРАН/Си/С++-вызовы
из библиотек, которые не тредо-безопасны. Например, в среде, где malloc
не тредо-безопасен, malloc
не должен использоваться библиотекой
MPI.
Некоторые разработчики могут захотеть использовать различные библиотеки
MPI для различных уровней поддержки треда. Они могут делать так,
используя динамическую связь и выбирая, какая библиотека будет связана, когда
вызван MPI_INIT_THREAD
. Если это не возможно, то оптимизация для
более низких уровней поддержки треда произойдут только, когда уровень
требуемой поддержки треда определен во время редактирования. []
Следующая функция может использоваться для запроса текущего уровня поддержки треда.
MPI_QUERY_THREAD(provided)
OUT | provided |
обеспеченный уровень поддержки треда (целое число) |
int MPI_Query_thread(int *provided)
MPI_QUERY_THREAD (PROVIDED, IERROR)
INTEGER PROVIDED, IERROR
int MPI::Query_thread()
Вызов возвращает в provided
текущий уровень поддержки треда. Это
было бы значение, возвращаемое MPI_INIT_THREAD
в provided
,
если MPI был инициализирован вызовом MPI_INIT_THREAD()
.
MPI_IS_THREAD_MAIN(flag)
OUT | flag |
истина, если вызываемый тред является основным тредом, иначе ложь (логический) |
int MPI_Is_thread_main(int *flag)
MPI_IS_THREAD_MAIN(FLAG, IERROR)
LOGICAL FLAG
INTEGER IERROR
bool MPI::Is_thread_main()
Эта функция может вызываться тредом, чтобы выяснить, является ли он
основным тредом (тред, который вызвал MPI_INIT
или
MPI_INIT_THREAD
).
Все подпрограммы, перечисленные в этом разделе должны быть поддержаны всеми реализациями MPI.
Объяснение:
Библиотеки MPI должны обеспечить эти вызовы, даже если они не
поддерживают треды, так, чтобы переносимый код, который содержит обращения
к этим функциям, был способен связаться правильно. MPI_INIT
продолжает поддерживаться для обеспечения совместимости с текущими кодами
MPI. []
Совет пользователям:
Возможно породить треды прежде, чем инициализирован MPI, но никакой
вызов MPI, кроме MPI_INITIALIZED
, не должен быть выполнен
этими тредами, пока
MPI_INIT_THREAD
не вызван одним из тредов
(который, таким образом, становится основным тредом). В частности, возможно
ввести выполнение MPI с многопоточным процессом.
Назначенный уровень поддержки треда является глобальным свойством
процесса MPI, который может быть определен только однажды, когда
MPI инициализирован на том процессе (или перед этим). Переносные
библиотеки третьей стороны должны быть написаны, чтобы приспособить любой
назначенный уровень поддержки треда. Иначе их использование будет
ограничено определенному уровню(ням) поддержки треда. Если такая
библиотека может работать только с определенным уровнем поддержки
треда, например, только с MPI_THREAD_MULTIPLE
, то
MPI_QUERY_THREAD
может использоваться, чтобы проверить,
инициализировал ли пользователь MPI с нужным уровнем
поддержки треда и, если нет, вызывает исключительную ситуацию. []