Односторонние коммуникации предъявляют те же требования к процессу выполнения, что и двухточечные коммуникации: как только взаимодействие становится возможным, гарантируется, что оно выполнится. RMA вызовы должны иметь локальную семантику, за исключением тех случаев, когда это необходимо для синхронизации с другими RMA вызовами.
Существует некоторая нечеткость в определении времени, когда RMA
коммуникации становятся возможным. Эта нечеткость обеспечивет
разработчику большую гибкость, чем двухточечные коммуникации. Доступ к
окну адресата становится возможным, как только выполнится соответствующая
синхронизация (такая как MPI_WIN_FENCE
или MPI_WIN_POST
). В
инициаторе RMA коммуникации могут стать возможными сразу же, как только
выполнится
соответствующий вызов get
, put
или accumulate
, или
после того, как будет выполнен следующий синхронизационный вызов.
Коммуникации должны выполняться, как только они станут возможными как для
инициатора, так и для адресата.
Рассмотрим фрагмент кода в примере 4.4. Некоторые вызовы могут выполнять
блокирование, если окно адресата не предоставлено для доступа. Однако, если
окно адресата предоставлено для доступа, тогда фрагмент кода должен выполниться.
Передача данных может начаться, как только произойдет вызов put
, но может
быть отложена до тех пор, пока не произойдет соответствующий вызов
complete
.
Рассмотрим фрагмент кода в примере 4.5. Некоторые вызовы могут выполнять блокирование, если другой процесс удерживает конфликтующую блокировку. Однако, если конфликтующая блокировка не держится, тогда фрагмент кода должен выполниться.
Рассмотрим код, проиллюстрированный на рис. 6.6. Каждый процесс обновляет
окно другого процесса, используя операцию put
, затем обращается к
собственному окну. Вызовы post
не блокирующие, и должны
выполниться. Как только произошел вызов post
, RMA доступ к окну
установлен, так что каждый процесс должен выполнить последовательность
вызовов start-put-complete
. Как только это сделано, должны
выполниться вызовы wait
на обоих процессах. Таким образом, это
взаимодействие не должно зайти в тупик, невзирая на количество переданных
данных.
Предположим, в последнем примере, что порядок вызовов post
и
START
обратен на каждом процессе. Тогда код может зайти в тупик,
так как каждый процесс может блокироваться на вызове start
, ожидая
пока не произойдет сооветствующий вызов post
. Так же, программа
зайдет в тупик, если порядок вызовов complete
и wait
обратен
на каждом процессе.
Следующие два примера иллюстрируют факт, что синхронизация между
complete
и wait
несимметричная: вызов wait
блокируется,
пока выполняется complete
, но не наоборот. Рассмотрим код,
иллюстрированный на рис 6.7. Этот код зайдет в тупик: wait
процесса 1 блокируется, пока не выполнятся вызовы процесса 0, и
receive
процесса 0 блокируется, пока процесс 1 вызывает send
.
Рассмотрим, с другой стороны, код, проиллюстрированный на рис 6.8. Этот
код не зайдет в тупик. Как только процесс 1 вызывает post
, тогда
последовательность start
, put
, complete
на процессе 0
может продолжаться до завершения. Процесс 0 достигнет вызова send
,
позволяя выполниться вызову receive
процесса 1.
Объяснение:
MPI реализации должны гарантировать, что процесс делает
PROGRESS
на всех установленных взаимодействиях, в которых он
принимает участие, пока заблокирован на MPI вызове. Это справедливо для
SEND-RECEIVE
взаимодействия и также касается RMA взаимодействия.
Таким образом, в примере на рис 6.8, вызовы put
и complete
процесса 0 должны выполниться, пока процесс 1 блокирован на вызове
receive
. Это может потребовать участия процесса 1, например, чтобы
передать данные put
, пока он заблокирован на вызове receive
.
Подобный вопрос состоит в том, должно ли происходить такое выполнение в
то время, когда процесс занят вычислением, или блокирован в не-MPI вызове?
Предположим, что в последнем примере пара send-receive
заменяется на пару
write-to-socket/read-from-socket
. Тогда MPI не определяет, удалось
ли избежать взаимной блокировки (deadlock). Предположим, что блокирующий
receive
процесса 1 заменен на очень длинный вычисляющий цикл.
Тогда, в соответствии с интерпретацией MPI стандарта, процесс 0 должен
вернуться из выполнения вызова после ограниченной задержки, даже если
процесс 1 не достиг какого-нибудь MPI вызова в этот период времени. В
соответствии с другой интерпретацией, вызов complete
может
блокироваться, пока процесс 1 не достигнет вызова wait
, или не
достигнет другого MPI вызова. Если процесс попал в бесконечный
вычислительный цикл, качественное поведение одинаково в обеих
интерпретациях: в этом случае разница не имеет значения. Тем не менее,
количественные ожидания различны. Разные MPI реализации отображают эти
разные интерпретации. В то время, как эта двусмысленность неудачна, она,
кажется, не затрагивает многие реальные коды. MPI форум решил не фиксировать,
какая интерпретация стандарта является правильной, так как проблема очень
спорна, и решение больше влияло бы на разработчиков, и меньше на
пользователей. []