Описание односторонных операций не может точно описать, что происходит к примеру, когда несколько процессов обращаются к одному окну-адресату. Данный раздел предоставляет более точное описание семантики RMA операций, и в частности, важен для точного понимания, что происходит (и что допускается согласно MPI-1) с несколькими процессами, которые обращаются к одному окну как с использованием, так и без использования MPI-1 операций RMA.
Семантика RMA операций лучше всего понимается в предположении, что система
поддерживает отдельную, разделяемую всеми (public) копию каждого
окна в дополнение к оригинальной приватной копии, расположенной в
памяти процесса. В памяти процесса существует только один экземпляр
каждой переменной, но в тоже время существует другая разделяемая
всеми копия переменной для каждого окна, которое ее содержит.
load
обращается к экземпляру в памяти процесса (это включает MPI
отправления). store
обращается и обновляет экземпляр в памяти
процесса (это включает MPI прием), но обновление может влиять на другие
разделяемые копии тех же адресов. get
в окне обращается к
разделяемой копии этого окна. put
или accumulate
в окне
обращается и обновляет разделяемую копию этого окна, но обновление может
влиять на приватную копию тех же позиций в памяти процесса, и на
разделяемые копии других перекрывающихся окон. Это проиллюстрировано на
Рис 4.5.
Нижеследующие правила определяют крайний срок, при котором операция должна
выполнится в инициаторе и в адресате. Обновление, выполненное вызовом
get
в памяти инициатора становится видимым, когда операция
get
выполняется в инциаторе (или раньше); обновление, произведенное
вызовом put
или accumulate
в разделяемой копии окна
получателя становится видимым, когда put
или accumulate
выполняются в адресате (или раньше). Правила так же определяют крайний
срок, когда обновление одной оконной копии становится видимым в другой
перекрывающейся копии.
MPI_WIN_COMPLETE
, MPI_WIN_FENCE
или MPI_WIN_UNLOCK
,
которые синхронизируют эти обращения в инициаторе.
MPI_WIN_FENCE
, тогда операция завершена в адресате
соответствующим вызовом MPI_WIN_FENCE
, созданным процессом
получателем.
MPI_WIN_COMPLETE
, тогда операция завершается в адресате
соответствующим вызовом MPI_WIN_WAIT
, созданным процессом
получателем.
MPI_WIN_UNLOCK
, тогда операция завершается в получателе
таким же вызовом MPI_WIN_UNLOCK
.
MPI_WIN_POST
,
MPI_WIN_FENCE
или MPI_WIN_UNLOCK
в том же окне
его владельцем.
put
или accumulate
становится видимым в приватной
копии в памяти процесса не позже, чем в том окне выполнится последующий
вызов MPI_WIN_WAIT
, MPI_WIN_FENCE
или MPI_WIN_LOCK
,
запущенный владельцем окна.
Вызов MPI_WIN_FENCE
или MPI_WIN_WAIT
, который завершает
передачу из разделяемой копии в приватную копию (6) является тем же
вызовом, который завершает операцию put
или accumulate
в
оконной копии (2,3). Если обращение put
или accumulate
синхронизировалось с lock
, тогда обновление оконной разделяемой
копии завершается, как только обновляющий процесс выполнит
MPI_WIN_UNLOCK
. С другой стороны, обновление приватной копии в
памяти процесса может задержаться, пока процесс-получатель не выполнит
синхронизационный вызов к этому окну (6). Таким образом, обновление
памяти процесса всегда можно отложить до тех пор, пока процесс не выполнит
подходящий синхронизационный вызов. Обновления оконной разделяемой копии
также можно задержать до тех пор, пока владелец окна не выполнит
синхронизационный вызов, если используются вызовы fence
или
post-start-complete-wait синхронизация. Только когда используется
lock
синхронизация, становится необходимым обновлять оконную
разделяемую копию, даже если владелец окна не выполняет никакого
относящегося к этому синхронизационного вызова.
Правила, представленные выше, также неявно определяют, когда обновление
оконной разделяемой копии становится видимым в другой перекрывающейся
оконной разделяемой копии. Рассмотрим, например, два перекрывающихся окна,
win1
и win2
. Вызов MPI_WIN_FENCE(0,win1)
, сделанный
владельцем окна, делает видимым в памяти процесса предыдущее обновление
окна win1
удаленным процессом. Последующий вызов
MPI_WIN_FENCE(0,win2)
делает эти обновления видимыми в разделяемой
копии win2
.
Правильная программа должна подчиняться следующим правилам.
accumulate
, которые используют ту же
операцию, с одним и тем же предопределенным типом данных, и в одном и том же
окне.
put
или accumulate
не должны обращаться к окну
адресата после того, как локальный вызов update
или put
или
accumulate
к другому (перекрывающемуся) окну-адресату начал
обновление окна-адресата до тех пор, пока обновление не станет
видимым в оконной разделяемой копии. Наоборот, локальное обновление
адресов в окне в памяти процесса не должно начинаться после того, как
обновление put
или accumulate
станет видимым в памяти
процесса. В обоих случаях, на операции накладываются ограничения,
даже если они обращаются к отдельным позициям в окне.
Программа является ошибочной, если она нарушает эти правила.
Объяснение:
Последнее ограничение на правильный RMA доступ может показаться
чрезмерным, поскольку оно запрещает одновременный доступ к
неперекрывающимся позициям в окне. Причина этого ограничения то, что на
некоторых архитектурах могут быть необходимы явные когерентные
восстановительные операции в точках синхронизации. Могут быть необходимы
разные операции для позиций, которые были локально обновлены при помощи
stores
и для позиций, которые были удаленно обновлены операциями
put
или accumulate
. Без этого ограничения MPI библиотеке
придется точно отслеживать, какие позиции в окне обновлялись вызовом
put
или accumulate
. Дополнительные расходы на поддержку
такой информации считаются недопустимыми. []
Совет пользователям: Пользователь может писать правильные программы, следуя нижеизложеным правилам:
fence
каждое окно или
обновляется вызовами put
или accumulate
, или обновляется
локальными stores
, но либо первое, либо второе. К адресам,
обновленным вызовами put
или accumulate
, не должны обращаться
во время одного и того же интервала (за исключением одновременных
обновлений одних и тех же адресов при помощи вызовов accumulate
).
Адреса, к которым обращались вызовами get
, не должны обновляться в
течение того же периода.
put
или accumulate
.
К адресам, обновленным вызовами put
или accumulate
, не должны
обращаться, пока окно предоставлено для доступа (за исключением
одновременных обновлений одних и тех же адресов вызовами
accumulate
). Адреса, к которым обращались с помощью вызовов
get
, не должны обновляться, пока окно предоставляется для доступа.
При помощи post-start
синхронизации, процесс-получатель может
сообщить инициатору, что окно готово для RMA доступа; с помощью
complete-wait
синхронизации инициатор может сообщить процессу-
адресату, что он закончил свой RMA доступ к окну.
accumulate
обращения) защищены совместно
используемыми блокировками, как для локального доступа, так и для RMA.
MPI_WIN_FENCE
, если RMA
обращения к окну синхронизированы при помощи вызовов fence
; после
локального
вызова MPI_WIN_WAIT
, если обращения синхронизированы при помощи
post-start-complete-wait; после вызова MPI_WIN_UNLOCK
в
инициаторе (локальном или удаленном), если обращения синхронизируются
блокировками.
В дополнение к вышесказанному, процесс не должен обращаться к локальному
буферу операции get
, пока операция не выполнилась, и не должен
обновлять локальный буфер операции put
или accumulate
, пока
не выполнится эта операция. []