The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа
next up previous contents
Next: Персистентные коммуникационные запросы Up: Парные межпроцессные обмены Previous: Множественные завершения   Contents

Проба и отмена

Операции MPI_PROBE и MPI_IPROBE позволяют проверить входные сообщения без их реального приема. Пользователь затем может решить, как ему принимать эти сообщения, основываясь на информации, возвращенной при пробе (преимущественно, на информации, возвращенной аргументом status). В частности, пользователь может выделить память для приемного буфера по величине опробованного сообщения.

Операция MPI_CANCEL позволяет отменить ждущие сообщения. Инициация операций получения или отправки связывает пользовательские ресурсы (буфера процесса-получателя или отправителя) и отмена может оказаться необходимой, чтобы освободить эти ресурсы.

Синтаксис функции MPI_IPROBE представлен ниже.

MPI_IPROBE(source, tag, comm, flag, status)
IN source номер процесса-отправителя или MPI_ANY_SOURCE (целое)
IN tag значение тэга или MPI_ANY_TAG (целое)
IN comm коммуникатор (дескриптор)
OUT flag (логическое значение)
OUT status статус (статус)

int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status)

MPI_IPROBE(SOURCE, TAG, COMM, FLAG, STATUS, IERROR)
LOGICAL FLAG
INTEGER SOURCE, TAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR

bool MPI::Comm::Iprobe(int source, int tag, MPI::Status& status) const

bool MPI::Comm::Iprobe(int source, int tag) const

Функция MPI_IPROBE (source, tag, comm, flag, status) возвращает flag = true, если имеется сообщение, которое может быть получено и которое соответствует образцу, описанному аргументами source, tag, и comm. Вызов соответствует тому же сообщению, которое было бы получено с помощью вызова MPI_RECV (..., source, tag, comm, status), выполненного на той же точке программы, и возвращает статус с теми же значениями, которые были бы возвращены MPI_RECV(). Другими словами, вызов возвращает flag = false, и оставляет статус неопределенным.

Если MPI_IPROBE возвращает flag = true, тогда содержание статусного объекта может быть впоследствии получено так, как описано в разделе 3.2.5, с целью определить источник, тэг и длину опробованного сообщения. Последующий прием, выполненный с тем же самым контекстом и тэгом, возвращенным в status вызовом MPI_IPROBE, будет получать сообщение, которое соответствует пробе, если после пробы не вмешается какое-либо другое сообщение. Если принимающий процесс является многопоточным, то ответственность за выполнение последнего условия возлагается на пользователя.

Аргумент source функции MPI_PROBE может быть MPI_ANY_SOURCE, это позволяет опробовать сообщения из произвольного источника и/или с произвольным тэгом. Однако, специфический контекст обмена обязан создаваться только при помощи аргумента comm.

Сообщение не обязательно должно быть получено сразу после опробования, кроме того оно может опробоваться несколько раз перед его получением.

Синтаксис функции MPI_PROBE представлен ниже.

MPI_PROBE (source, tag, comm, status)
IN source номер источника или MPI_ANY_SOURCE (целое)
IN tag значение тэга или MPI_ANY_TAG (целое)
IN comm коммуникатор (дескриптор)
OUT status статус (статус)

int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status) 

MPI_PROBE(SOURCE, TAG, COMM, STATUS, IERROR)
INTEGER SOURCE, TAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR 

void MPI::Comm::Probe(int source, int tag, MPI::Status& status) const 

void MPI::Comm::Probe(int source, int tag) const

MPI_PROBE ведет себя подобно MPI_IPROBE, исключая тот факт, что функция MPI_PROBE является блокирующей и заканчивается только после того, как соответствующее сообщение было найдено.

MPI реализация MPI_PROBE и MPI_IPROBE нуждается в гарантии продвижения: если обращение к MPI_PROBE уже было запущено процессом, и посылка, которая соответствует пробе, уже инициирована тем же процессом, тогда вызов MPI_PROBE будет завершен, если сообщение не будет получено другой конкурирующей операцией приема (которая выполняется другой ветвью опробуемого процесса). Аналогично, если процесс ожидает выполнения MPI_IPROBE и соответствующее сообщение было запущено, тогда обращение к MPI_IPROBE рано или поздно возвратит flag = true, если сообщение не получено другой конкурирующей приемной операцией.

Пример 3.17 Использование блокирующей пробы для ожидания входного сообщения.

       CALL MPI_COMM_RANK(comm, rank, ierr) 
       IF (rank.EQ.0) THEN 
            CALL MPI_SEND(i, 1, MPI_INTEGER, 2, 0, comm, ierr) 
       ELSE IF(rank.EQ.1) THEN 
            CALL MPI_SEND(x, 1, MPI_REAL, 2, 0, comm, ierr) 
       ELSE   ! rank.EQ.2 
           DO i=1, 2 
              CALL MPI_PROBE(MPI_ANY_SOURCE, 0, 
                              comm, status, ierr) 
              IF (status(MPI_SOURCE) = 0) THEN 
100            CALL MPI_RECV(i,1,MPI_INTEGER,0,0,comm, status, ierr) 
              ELSE 
200            CALL MPI_RECV(x,1,MPI_REAL,1,0,comm, status, ierr) 
              END IF 
           END DO 
       END IF

Каждое сообщение принимается с правильным типом.

Пример 3.18 Программа подобна предыдущей, но теперь в ней имеется проблема.

       CALL MPI_COMM_RANK(comm, rank, ierr) 
       IF (rank.EQ.0) THEN 
            CALL MPI_SEND(i, 1, MPI_INTEGER, 2, 0, comm, ierr) 
       ELSE IF(rank.EQ.1) THEN 
            CALL MPI_SEND(x, 1, MPI_REAL, 2, 0, comm, ierr) 
       ELSE 
           DO i=1, 2 
              CALL MPI_PROBE(MPI_ANY_SOURCE, 0, 
                              comm, status, ierr) 
              IF (status(MPI_SOURCE) = 0) THEN 
100                CALL MPI_RECV(i, 1, MPI_INTEGER, MPI_ANY_SOURCE, 
                                 0, comm, status, ierr) 
              ELSE 
200                CALL MPI_RECV(x, 1, MPI_REAL, MPI_ANY_SOURCE,
                                 0, comm, status, ierr)
              END IF
           END DO
       END IF

Здесь пример 3.17 слегка модифицирован, используется MPI_ANY_SOURCE, как аргумент sourse в двух вызовах приема, обозначенных метками 100 и 200. Теперь программа некорректна: операция приема может получать сообщение, которое отличается от сообщения, опробованного предыдущим обращением к MPI_PROBE.

Совет разработчикам: Вызов MPI_PROBE (source, tag, comm, status) будет соответствовать сообщению, которое было бы получено функцией MPI_RECV (...source, tag, comm, status), выполненной в этой же точке программы. Предположим, что это сообщение имеет источник s, тэг t и коммуникатор c. Если тэг имел в вызове пробы значение MPI_ANY_TAG, тогда опробованное значение будет самым ранним ждущим сообщением от источника с коммуникатором с и любым тэгом; в любом случае опробованное сообщение будет самым ранним ждущим сообщением от источника s, с тэгом t и коммуникатором c. Операция приема, выполненная после пробы, которая использует тот же самый коммуникатор, как и проба, и использующая тэг и источник, возвращенные пробой, обязана принять это сообщение, если оно уже не было принято другой приемной операцией.[]

Синтаксис функции MPI_CANCEL представлен ниже.

MPI_CANCEL (request)
IN request коммуникационный запрос (дескриптор)

int MPI_Cancel(MPI_Request *request)

MPI_CANCEL(REQUEST, IERROR)
INTEGER REQUEST, IERROR

void MPI::Request::Cancel () const

Обращение к MPI_CANCEL маркирует для отмены ждущие неблокирующие операции обмена (передачи или приема). Вызов cancel является локальным. Он заканчивается немедленно, возможно перед действительной отменой обмена. После маркировки необходимо завершить эту операцию обмена, используя вызов MPI_REQUEST_FREE, MPI_WAIT или MPI_TEST (или любые производные операции).

Если обмен маркирован для отмены, тогда вызов MPI_WAIT для этой операции гарантирует завершение, невзирая на активность других процессов (то есть MPI_WAIT ведет себя как локальная функция); аналогично, если MPI_TEST вызывается повторно в цикле занятого ожидания для отмены обмена, тогда MPI_TEST будет неизбежно успешно закончен.

MPI_CANCEL может быть использован для отмены обмена, который использует персистентный запрос (см. раздел 3.9), тем же способом, который используется для неперсистентных запросов. Успешная отмена отменяет активный обмен, но не сам запрос. После обращения к MPI_CANCEL и затем к MPI_WAIT или MPI_TEST запрос становится неактивным и может быть активирован для нового обмена.

Успешная отмена буферизованной передачи освобождает буферное пространство, занятое ждущим сообщением.

Должно выполняться следующее условие: либо отмена имеет успех, либо имеет успех обмен, но не обе ситуации вместе. Если передача маркирована для отмены, тогда обязательно должна быть ситуация, когда либо передача завершается нормально (посланное сообщение принято процессом назначения), или передача отменена успешно (никакая часть сообщения не принята по адресу назначения). Тогда любой соответствующий прием закрывается другой передачей. Если прием маркирован для отмены, тогда обязан быть случай, когда прием завершился нормально, или этот прием успешно отменен (никакая часть приемного буфера не изменена). Тогда любая соответствующая передача должна быть удовлетворена другим приемом.

Если операция была отменена, тогда информация об этом будет возвращена в в аргумент статуса операции, которая завершает обмен.

Синтаксис функции MPI_TEST_CANCELLED представлен ниже.

MPI_TEST_CANCELLED (status, flag)
IN status статус (статус)
OUT flag (логический тип)

int MPI_Test_cancelled(MPI_Status *status, int *flag) 

MPI_TEST_CANCELLED(STATUS, FLAG, IERROR)
LOGICAL FLAG 
INTEGER STATUS(MPI_STATUS_SIZE), IERROR 

bool MPI::Status::Is_cancelled () const

Функция MPI_TEST_CANCELLED возвращает flag = true, если обмен, связанный со статусным объектом, был отменен успешно. В этом случае все другие поля статуса (такие как count или tag) не определены. В противном случае возвращается flag = false. Если приемная операция может быть отменена, то сначала можно вызвать MPI_TEST_CANCELLED, чтобы проверить, была ли отменена операция (перед проверкой других полей возвращенного статуса).

Совет пользователям: Отмена может быть дорогостоящей операцией, которую следует использовать в виде исключения.[]

Совет разработчикам: Если операция передачи использует ``жадный'' (``eager'') протокол (данные передаются получателю еще до того, как инициирован соответствующий прием), тогда отмена этой передачи может потребовать обмена с предполагаемым получателем, чтобы освободить занятые буфера. На некоторых системах это может потребовать прерывания предполагаемого процесса-получателя. Заметим, что хотя для реализации MPI_CANCEL может потребоваться обмен, это все еще локальная операция, поскольку ее завершение не зависит от кода, выполняемого другими процессами. Если обработка необходима на другом процессе, это должно быть прозрачно для приложения (отсюда необходимость прерывания и наличия обработчика прерываний).[]


next up previous contents
Next: Персистентные коммуникационные запросы Up: Парные межпроцессные обмены Previous: Множественные завершения   Contents
Alex Otwagin 2002-12-10



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру