Выполнение операции put
похоже на выполнение операции send
процессом-инициатором и соответствующего receive
процессом-адресатом. Очевидная разница состоит в том, что все аргументы
предоставляются одним вызовом - вызовом, который исполняется инициатором.
MPI_PUT(origin_addr, origin_count, origin_datatype, target_rank,
target_disp, target_count, target_datatype, win)
IN | origin_addr |
начальный адрес буфера инициатора (по выбору) | |
IN | origin_count |
число записей в буфере инициатора (неотрицательное целое) | |
IN | origin_datatype |
тип данных каждой записи в буфере инициатора (дескриптор) | |
IN | target_rank |
номер получателя (неотрицательное целое) | |
IN | taget_disp |
смещение от начала окна до буфера получателя (неотрицательное целое) | |
IN | target_count |
число записей в буфере получателя (неотрицательное целое) | |
IN | target_datatype |
тип данных каждой записи в буфере получателя (дескриптор) | |
IN | win |
оконный объект, используемый для коммуникации (дескриптор) |
int MPI_Put(void *origin_addr, int origin_count, MPI_Datatype origin_datatype,
int target_rank, MPI_Aint target_disp, int target_count,
MPI_Datatype target_datatype, MPI_Win win)
MPI_PUT(ORIGIN_ADDR, ORIGIN_COUNT, ORIGIN_DATATYPE,
TARGET_RANK, TARGET_DISP, TARGET_COUNT,
TARGET_DATATYPE, WIN, IERROR)
<type> ORIGIN_ADDR(*)
INTEGER(KIND=MPI_ADDRESS_KIND) TARGET_DISP
INTEGER ORIGIN_COUNT, ORIGIN_DATATYPE, TARGET_RANK,
TARGET_COUNT, TARGET_DATATYPE, WIN, IERROR
void MPI::Win::Put(const void* origin_addr, int origin_count,
const MPI::Datatype& origin_datatype,
int target_rank, MPI::Aint target_disp,
int target_count,
const MPI::Datatype& target_datatype) const
MPI_PUT
передает origin_count
следующих друг за другом
записей типа, определяемого
[]origin_datatype
, начиная с адреса
origin_addr
на узле инициатора, узлу адресата, определяемому парой
win
и tаrget_rank
. Данные записываются в буфер адресата по
адресу target_addr =
window_base
+ target_disp
* disp_unit
,
где window_base
и disp_unit
базовый адрес и
единица смещения окна, определенные при инициализации оконного обьекта
процессом-получателем.
Буфер получатель определяется аргументами target_count
и
target_datatype
.
Передача данных происходит так же, как если бы инициатор
выполнил операцию send
с аргументами origin_addr
,
origin_count
, origin_datatype
, target rank
,
tag
, comm
, и процесс-получатель выполнил операцию
receive
с аргументами taget_addr
, target_datatype
,
source
, tag
, comm
, где target_addr
- это адрес
буфера получателя, вычисленный, как объяснялось выше, а comm
- это
коммуникатор для группы win
.
Взаимодействие должно удолетворять таким же ограничениям, какие существуют
для передачи сообщений. Target_datatype
не может определять
перекрывающееся записи в буфере получателя. Посланное сообщение должно
помещаться без усечения в буфер получателя. К тому же, буфер
получателя должен помещаться в окне получателе.
Аргумент target_datatype
является дескриптором типа данных объекта,
определенного в
процессе-инициаторе. Тем не менее, этот объект
интерпретируется процессом-получателем: результат при этом такой же, как
если бы тип данных объекта адресата был определен процессом-адресатом с
использованием той же последовательности вызовов, которая использовалась
для его определения инициатором. Тип данных адресата должен содержать
только относительные смещения, а не абсолютные адреса. Тоже справедливо
для get
и accumulate
.
Совет пользователям:
Аргумент target_datatype
- это дескриптор типа данных объекта,
который определен в процессе-адресате, несмотря на то, что он определяет
размещение данных в памяти инициатора. Это не вызывает проблем в
однородной среде или в неоднородной среде, если используются только
переносимые типы данных (переносимые типы данных определены в разделе
2.4).
На производительность передачи данных при записи (put transfer
) на
некоторых системах значительно влияет выбор расположения окна, форма
и расположение буферов инициатора и адресата: передачи в окно адресата
в памяти, распределенной с помощью MPI_ALLOC_MEM
, могут быть
гораздо быстрее на системах с общей памятью; пересылки из смежных буферов
будут быстрее на большинстве, если не на всех системах; выравнивание
коммуникационных буферов также может влиять на производительность. []
Совет разработчикам:
Высококачественная реализация постарается предотвратить удаленный доступ к
памяти вне пределов окна, которое было предоставлено процессом для
доступа, как для нужд отладки, так и для защиты с помощью кодов
клиент-сервер, которые используют RMA. Это означает что
высококачественная реализация, если это возможно, будет проверять границы
окон при каждом RMA вызове, и инициирует MPI_EXCEPTION
, если в
вызове инициатора возникнет ситуация выхода за границы окна. Заметим, что
это условие может проверяться в инициаторе. Конечно же, дополнительная
безопасность, достигаемая такими проверками, должна взвешиваться на предмет
дополнительной стоимости таких вызовов. []