next up previous contents
Next: Lock Up: Синхронизационные вызовы Previous: Fence   Contents

Общая синхронизация с активным адресатом

MPI_WIN_START(group, assert, win)

IN group группа инициаторов (дескриптор)  
IN assert программный ассерт(целое)  
IN win объект окна (дескриптор)  

int MPI_Win_start(MPI_Group group, int assert, MPI_Win win)

MPI_WIN_START(GROUP, ASSERT, WIN, IERROR) INTEGER GROUP, ASSERT, WIN, IERROR

void MPI::Win::Start(const MPI::Group& group, int assert) const

Вызов начинает период RMA доступа к win. Выданные во время этого периода RMA вызовы к win должны иметь доступ только к процессам в group. Каждый процесс в group должен вызвать соответствующий вызов MPI_WIN_POST. RMA обращение к каждому окну-адресату, если необходимо, будет задержано, пока процесс-адресат не выполнит соответствующий вызов MPI_WIN_POST. WPI_WIN_START может блокироваться, пока выполняются соответствующие вызовы MPI_WIN_POST, но это не обязательно.

Аргумент assert используется для обеспечения соглашений о контексте вызова, которые могут использоваться для разных оптимизаций. Это описывается в разделе 4.4.4. Значение assert = 0 всегда справедливо.

MPI_WIN_COMPLETE(win)

IN win объект окна (дескриптор)  

int MPI_Win_complete(MPI_Win win)

MPI_WIN_COMPLETE(WIN, IERROR) INTEGER WIN, IERROR

void MPI::Win::Complete() const

Вызов завершает период RMA доступа к win, начатый вызовом MPI_WIN_START. Все коммуникационные RMA вызовы к win, созданные во время этого периода, завершатся в инициаторе, когда произойдет возврат из вызова.

MPI_WIN_COMPLETE заставляет завершиться предшествующие RMA вызовы в инициаторе, но не в адресате. Вызов put или accumulate может еще не выполниться у адресата, в то время, как он уже выполнился у инициатора.

Рассмотрим последовательность вызовов в нижеследующем примере.

Пример 6.4

MPI_Win_start(group, flag, win); MPI_Put(...,win); MPI_Win_complete(win);

Возврат из вызова MPI_WIN_COMPLETE не произойдет, пока в инициаторе не выполнится вызов put; и операция put получит доступ к окну-адресату только после того, как за вызовом MPI_WIN_START будет выдан процессом-адресатом соответствующий вызов MPI_WIN_POST. Это по прежнему оставляет большой выбор разработчикам. Вызов MPI_WIN_START может блокироваться, пока не произойдет соответствующий вызов MPI_WIN_POST на всех процессах получателях. Также можно встретить реализации, где вызов MPI_WIN_START не является блокирующим, однако вызов MPI_PUT блокируется, пока не произойдет соответствующий вызов MPI_WIN_POST; или реализации, где первые два вызова не являются блокирующими, но вызов MPI_WIN_COMPLETE блокируется, пока не осуществится вызов MPI_WIN_POST; или даже реализации, где все три вызова могут выполняться до того, как какой-нибудь процесс вызовет MPI_WIN_POST, в последнем случае, данные для put должны буферизоваться, чтобы позволить put выполниться в инициаторе, перед тем как выполниться в адресате. Тем не менее, если создан вызов MPI_WIN_POST, вышестоящая последовательность должна выполняться без дальнейших зависимостей.

MPI_WIN_POST(group, assert, win)

IN group группа инициаторов (дескриптор)  
IN assert программный ассерт(целое)  
IN win объект окна (дескриптор)  

int MPI_Win_post(MPI_Group group, int assert, MPI_Win win)

MPI_WIN_POST(GROUP, ASSERT, WIN, IERROR) INTEGER GROUP, ASSERT, WIN, IERROR

void MPI::Win::Post(const MPI::Group& group, int assert) const

Начинает период предоставления RMA доступа для локального окна, связанного с win. Только процессы в group должны иметь доступ к окну при помощи RMA вызовов к win во время этого периода. Каждый процесс в группе должен создать соответствующий вызов MPI_WIN_START. MPI_WIN_POST не блокируется.

MPI_WIN_WAIT(win)

IN win объект окна (дескриптор)  

int MPI_Win_wait(MPI_Win win)

MPI_WIN_WAIT(WIN, IERROR) INTEGER WIN, IERROR

void MPI::Win::Wait() const

Завершает RMA период предоставления RMA доступа к win, начатый вызовом MPI_WIN_POST. Этот вызов соответствует вызовам MPI_WIN_COMPLETE(win), созданным каждым инициатором, которые имели доступ к окну во время этого периода. Вызов MPI_WIN_WAIT будет блокироваться, пока не завершатся все соответствующие вызовы MPI_WIN_COMPLETE. Это гарантирует, что все инициаторы закончили свой RMA доступ к локальному окну. Когда вызов возвратится, все эти RMA обращения уже завершатся в окне-адресате.

\includegraphics[scale=0.7]{pic/6.4.eps}


Рисунок 6.4. Коммуникации с активным адресатом. Синхронизация представлена пунктирными стрелками, передача данных - сплошными.

Рис 6.4 Иллюстрирует использование этих четырех функций. Процесс 0 помещает данные в окна процессов 1 и 2, а процесс 3 помещает данные в окно процесса 2. Каждый вызов start перечисляет категории процессов, к чьим окнам будет выполнено обращение; каждый post вызов перечисляет категории процессов, которые выполняют доступ к локальному окну. Рисунок иллюстрирует возможный ход событий в предположении, что синхронизация сильная; при слабой синхронизации вызовы start, put или complete могут происходить перед соответствующими вызовами post.

MPI_WIN_TEST(win, flag)

IN win объект окна (дескриптор)  
OUT flag флаг успеха (logical)  

int MPI_Win_test(MPI_Win win, int *flag)

MPI_WIN_TEST(WIN, FLAG, IERROR) INTEGER WIN, IERROR LOGICAL FLAG

bool MPI::Win::Test() const

Этот вызов является неблокирующей версией MPI_WIN_WAIT. Он возвращает flag = true, если из вызова MPI_WIN_WAIT может быть выполнен возврат, и flag = false в противном случае. Эффект от возвращения MPI_WIN_TEST c flag = true такой же, как эффект от возвращения MPI_WIN_WAIT. Если возвращен flag = false, тогда у вызова нет видимого эффекта.

MPI_WIN_TEST должен вызываться только там, где можно вызвать MPI_WIN_WAIT. Как только произойдет возврат из test с кодом flag = true для некоторого оконного объекта, test не должен вызываться для этого окна, пока оно не будет снова предоставлено для доступа (posted).

Правила соответствия для вызовов post и start и для вызовов complete и wait могут быть получены из правил соответствия вызовов (send) и получений (receive), рассматривая следующую (частную) модель реализации. Предположим, что окно win связано со ``скрытым'' коммуникатором wincomm, используемым для коммуникационного взаимодействия процессами из win.

MPI_WIN_POST(group,0,win): инициирует неблокирующую отправку с тэгом tag0 каждому процессу в group, используя wincomm. Нет необходимости ожидать выполнения этих отправлений.

MPI_WIN_START(group,0,win): инициирует неблокирующий прием с тэгом tag0 от каждого процесса в group, используя wincomm. RMA доступ у окну процесса-адресата $i$ задерживается до тех пор, пока прием из процесса $i$ не будет выполнен.

MPI_WIN_COMPLETE(win): Инициирует неблокирующую отправку с тэгом tag1 к каждому процессу в группе предшествующего вызова start. Нет необходимости ожидать выполнения этих отправлений.

MPI_WIN_WAIT(win): инициирует неблокирующий прием с тэгом tag1 от каждого процесса в группе предшествующего вызова post. Ждите выполнения всех получений.

Гонки в правильной программе возникнуть не могут: Каждой отправке соответствует свое уникальное получение, и наоборот.

Объяснение: Дизайн общей синхронизации с активным адресатом требует, чтобы пользователь обеспечил полную информации о модели взаимодействия на каждом конце соединения: каждый инициатор определяет список адресатов, и каждый адресат определяет список инициаторов. Это обеспечивает максимальную гибкость (следовательно, эффективность) для разработчиков: каждая синхронизация может быть инициирована обеими сторонами, так как каждая ``знает в лицо'' другую. Это также обеспечивает максимальную защиту от возможных гонок. С другой стороны, дизайн требует, в общем случае, больше информации чем необходимо для RMA: обычно достаточно, чтобы инициатор знал категрию получателей, но не наоборот. Пользователи, которые захотят более ``анонимных'' коммуникаций, будут обязаны использовать механизм fence или lock.

Совет пользователям: Предположим что коммуникационная модель, которая представлена направленным графом $G=<V,E>$, с вершинами $V=\{0,....n-1\}$ и ребрами $E$, определенными с помощью $ij \in E$ если инициатор $i$ обращается к окну в процессе-адресате $j$. Затем каждый процесс $i$ выполняет вызов MPI_WIN_POST(ingroupi,...), сопровождаемый вызовом MPI_WIN_START(outgroupi,....), где $outgroup_i = \{j:ij \in E\}$ b $ingroup_i = \{j:ji \in E\}$. Вызов является пустым, и может быть опущен, если аргумент group пуст. После коммуникационных вызовов, каждый процесс, который вызвал start, вызовет complete. Наконец, каждый процесс, вызвавший post, вызовет wait.

Отметим, что каждый процесс может вызвать MPI_WIN_POST или MPI_WIN_START с аргументом group, у которого разные члены.


next up previous contents
Next: Lock Up: Синхронизационные вызовы Previous: Fence   Contents
Alex Otwagin 2002-12-10