| |
Часто запрос с одним и тем же набором аргументов повторно выполняется во внутреннем цикле параллельных вычислений. В такой ситуации можно оптимизировать обмен путем однократного включения списка аргументов в персистентный (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.[]
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |