Формирование сообщений при помощи упаковки и распаковки данных

Наряду с рассмотренными в п. 5.5.2 методами конструирования производных типов в MPI предусмотрен и явный способ сборки и разборки сообщений, содержащих значения разных типов и располагаемых в разных областях памяти.

Для использования данного подхода должен быть определен буфер памяти достаточного размера для сборки сообщения. Входящие в состав сообщения данные должны быть упакованы в буфер при помощи функции:

int MPI_Pack(void *data, int count, MPI_Datatype type, void *buf, int bufsize, int *bufpos, MPI_Comm comm),

где

· data — буфер памяти с элементами для упаковки;

· count — количество элементов в буфере;

· type — тип данных для упаковываемых элементов;

· buf — буфер памяти для упаковки;

· bufsize — размер буфера в байтах;

· bufpos — позиция для начала записи в буфер (в байтах от начала буфера);

· comm — коммуникатор для упакованного сообщения.

Функция MPI_Pack упаковывает count элементов из буфера data в буфер упаковки buf, начиная с позиции bufpos. Общая схема процедуры упаковки показана на рис. 5.8а.


Рис. 5.8. Общая схема упаковки и распаковки данных

Начальное значение переменной bufpos должно быть сформировано до начала упаковки и далее устанавливается функцией MPI_Pack. Вызов функции MPI_Pack осуществляется последовательно для упаковки всех необходимых данных. Так, в ранее рассмотренном примере набора переменных a, b и n для их упаковки необходимо выполнить:

bufpos = 0;MPI_Pack(&a, 1, MPI_DOUBLE, buf, buflen, &bufpos, comm);MPI_Pack(&b, 1, MPI_DOUBLE, buf, buflen, &bufpos, comm);MPI_Pack(&n, 1, MPI_INT, buf, buflen, &bufpos, comm);

Для определения необходимого размера буфера для упаковки может быть применена функция:

int MPI_Pack_size(int count, MPI_Datatype type, MPI_Comm comm, int *size),

где

· count — количество элементов в буфере;

· type — тип данных для упаковываемых элементов;

· comm — коммуникатор для упакованного сообщения;

· size — рассчитаный размер буфера.

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

После получения сообщения с типом MPI_PACKED данные могут быть распакованы при помощи функции:

int MPI_Unpack(void *buf, int bufsize, int *bufpos, void *data, int count, MPI_Datatype type, MPI_Comm comm),

где

· buf — буфер памяти с упакованными данными;

· bufsize — размер буфера в байтах;

· bufpos — позиция начала данных в буфере (в байтах от начала буфера);

· data — буфер памяти для распаковываемых данных;

· count — количество элементов в буфере;

· type — тип распаковываемых данных;

· comm — коммуникатор для упакованного сообщения.

Функция MPI_Unpack распаковывает, начиная с позиции bufpos, очередную порцию данных из буфера buf и помещает распакованные данные в буфер data. Общая схема процедуры распаковки показана на рис. 5.8б.

Начальное значение переменной bufpos должно быть сформировано до начала распаковки и далее устанавливается функцией MPI_Unpack. Вызов функции MPI_Unpack осуществляется последовательно для распаковки всех упакованных данных, при этом порядок распаковки должен соответствовать порядку упаковки. Так, в ранее рассмотренном примере упаковки для распаковки упакованных данных необходимо выполнить:

bufpos = 0;MPI_Unpack(buf, buflen, &bufpos, &a, 1, MPI_DOUBLE, comm);MPI_Unpack(buf, buflen, &bufpos, &b, 1, MPI_DOUBLE, comm);MPI_Unpack(buf, buflen, &bufpos, &n, 1, MPI_INT, comm);

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: