next up previous contents
Next: Совмещенные прием и передача Up: Парные межпроцессные обмены Previous: Проба и отмена   Contents

Персистентные коммуникационные запросы

Часто запрос с одним и тем же набором аргументов повторно выполняется во внутреннем цикле параллельных вычислений. В такой ситуации можно оптимизировать обмен путем однократного включения списка аргументов в персистентный (persistent) коммуникационный запрос и повторного использования этого запроса для инициации и завершения обмена.

Персистентный запрос, созданный таким образом, может восприниматься как коммуникационный порт или ``полуканал''. Он не обеспечивает полноты функций обычного канала, поскольку нет никакой связи между передающим и приемным портами. Эта конструкция позволяет уменьшить накладные расходы на коммуникацию между процессом и коммуникационным контроллером, но не расходы на коммуникацию между одним коммуникационным контроллером и другим.

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

Персистентный запрос создается одним из четырех следующих вызовов.

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

MPI_SEND_INIT (buf, count, datatype, dest, tag, comm, request)

IN buf начальный адрес буфера посылки (альтернатива)
IN count число посланных элементов (целое)
IN datatype тип каждого элемента (дескриптор)
IN dest номер процесса-получателя (целое)
IN tag тэг сообщения (целое)
IN comm коммуникатор(дескриптор)
OUT request коммуникационный запрос (дескриптор)

int MPI_Send_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_SEND_INIT(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR) <type> BUF(*) INTEGER REQUEST, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR MPI::Prequest MPI::Comm::Send_init(const void* buf, int count, const MPI::Datatype& datatype, int dest, int tag) const

MPI_SEND_INIT создает персистентный коммуникационный запрос для операции передачи стандартного режима и связывает для этого все аргументы операции передачи.

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

MPI_BSEND_INIT (buf, count, datatype, dest, tag, comm, request)

IN buf начальный адрес передающего буфера (альтернатива)
IN count число посланных элементов (целое)
IN datatype тип каждого элемента (дескриптор)
IN dest номер приемника (целое)
IN tag тэг сообщения (целое)
IN comm коммуникатор (дескриптор)
OUT request коммуникационный запрос (дескриптор)

int MPI_Bsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_BSEND_INIT(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR) <type> BUF(*) INTEGER REQUEST, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR MPI::Prequest MPI::Comm::Bsend_init (const void* buf, int count, const MPI::Datatype& datatype, int dest, int tag) const

MPI_BSEND_INIT создает персистентный коммуникационный запрос для буферизованного режима передачи.

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

MPI_SSEND_INIT (buf, count, datatype, dest, tag, comm, request)

IN buf начальный адрес буфера отправителя (альтернатива)
IN count число посланных элементов (целое)
IN datatype тип каждого элемента (дескриптор)
IN dest номер получателя (целое)
IN tag тэг сообщения (целое)
IN comm коммуникатор(дескриптор)
OUT request коммуникационный запрос (дескриптор)

int MPI_Ssend_init (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_SSEND_INIT(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR) <type> BUF(*) INTEGER REQUEST, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR MPI::Prequest MPI::Comm::Ssend_init(const void* buf, int count, const MPI::Datatype& datatype, int dest, int tag) const

MPI_SSEND_INIT создает персистентный коммуникационный запрос для синхронного режима операции посылки.

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

MPI_RSEND_INIT (buf, count, datatype, dest, tag, comm, request)

IN buf начальный адрес буфера отправителя (альтернатива)
IN count число посланных элементов (целое)
IN datatype тип каждого элемента (дескриптор)
IN dest номер получателя (целое)
IN tag тэг сообщения (целое)
IN comm коммуникатор(дескриптор)
OUT request коммуникационный запрос (дескриптор)

int MPI_Rsend_init (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_RSEND_INIT(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR) <type> BUF(*) INTEGER REQUEST, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR MPI::Prequest MPI::Comm::Rsend_init(const void* buf, int count, const MPI::Datatype& datatype, int dest, int tag) const

MPI_RSEND_INIT создает персистентный коммуникационный объект для режима по готовности операции посылки.

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

MPI_RECV_INIT(buf, count, datatype, source, tag, comm, request)

OUT buf начальный адрес приемного буфера (альтернатива)
IN count число полученных элементов (целое)
IN datatype тип каждого элемента (дескриптор)
IN source номер источника или MPI_ANY_SOURCE (целое)
IN tag тэг сообщения или MPI_ANY_TAG (целое)
IN comm коммуникатор (дескриптор)
OUT request коммуникационный запрос (дескриптор)

int MPI_Recv_init(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request) MPI_RECV_INIT(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, IERROR) <type> BUF(*) INTEGER COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, IERROR MPI::Prequest MPI::Comm::Recv_init(void* buf, int count, const MPI::Datatype& datatype, int source, int tag) const

Функция MPI_RECV_INIT создает персистентный запрос для операции приема. Аргумент buf маркируется как OUT, поскольку пользователь разрешает запись в приемный буфер, передавая аргумент MPI_RECV_INIT.

Персистентный запрос после создания не активен - никакого активного обмена не подключено к запросу.

Коммуникация (передача или прием), которая использует персистентный запрос, создается функцией MPI_START.

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

MPI_START(request)

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

int MPI_Start (MPI_Request *request) MPI_START (REQUEST, IERROR) INTEGER REQUEST, IERROR void MPI::Prequest::Start ()

Аргумент request - дескриптор, возвращенный одним из пяти предыдущих вызовов. Связанный с ним запрос должен быть не активен. Запрос становится активен сразу, как только сделан вызов.

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

Вызов MPI_START является локальным с семантикой, подобной семантике неблокирующей коммуникационной операции, описанной в разделе 3.7. Это означает, что обращение к MPI_START с запросом, созданным MPI_SEND_INIT, запускает обмен тем же способом, как при обращении к MPI_ISEND; обращение к MPI_START с запросом, созданным MPI_BSEND_INIT, запускает обмен тем же способом, как при обращении к MPI_IBSEND; и так далее.

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

MPI_STARTALL (count, array_of_requests)

IN count длина списка (целое)
INOUT array_of_requests массив запросов (массив of дескриптор)

int MPI_Startall(int count, MPI_Request *array_of_requests) MPI_STARTALL(COUNT, ARRAY_OF_REQUESTS, IERROR) INTEGER COUNT, ARRAY_OF_REQUESTS(*), IERROR static void MPI::Prequest::Startall (int count, MPI::Prequest array_of_requests[])

Запуск всех обменов связан с запросами в array_of_requests. Обращение к функции
MPI_STARTALL(count, array_of_requests) дает тот же самый эффект, что и обращения к функциям MPI_START(&array_of_requests[i]), выполненным для i=0, ..., count-1 в некотором произвольном порядке.

Обмен, который стартует по вызову MPI_START или MPI_STARTALL завершается обращением к MPI_WAIT, MPI_TEST или к одной из производных функций, описанных в разделе 3.7.5. Запрос становится неактивным после успешного завершения такого вызова. Запрос не снимается с назначения и может быть активирован вновь вызовами MPI_START или MPI_STARTALL.

Постоянный запрос удаляется вызовом MPI_REQUEST_FREE (раздел 3.7.3).

Обращение к MPI_REQUEST_FREE может выполняться в любой точке программы после старта персистентного запроса. Однако запрос будет снят с назначения только после того, как он становится неактивным. Активные приемные запросы не должны удаляться, иначе невозможно будет проверить, какой прием был завершен. Желательно удалить запросы, когда они не активны. Если следовать этому правилу, то функции, описанные в этом разделе, будут вызываться в последовательности вида

Create (Start Complete)*Free

где * указывает ноль или более повторений. Если некоторый коммуникационный объект используется в нескольких конкурирующих ветвях, то координация вызовов для соблюдения правильной последовательности выполнения, лежит на пользователе.

Операция передачи, инициированная MPI_START, может соответствовать любой операции приема; аналогичо, приемная операция , инициированная MPI_START, может принимать сообщения, сгенерированные любой операцией передачи.

Совет пользователям: Чтобы предупредить проблему с копированием аргументов и оптимизацией регистров, выполняемую компиляторами языка ФОРТРАН, следует обратить внимание на раздел 10.2.2 в стандарте MPI-2.[]


next up previous contents
Next: Совмещенные прием и передача Up: Парные межпроцессные обмены Previous: Проба и отмена   Contents
Alex Otwagin 2002-12-10