Кафедра ЮНЕСКО по НИТ1 Передача упакованных данных Параллельное программирование
Кафедра ЮНЕСКО по НИТ 2 Ограничение стандартных типов Коммуникационные операции позволяют посылать и получать последовательность элементов одного типа, занимающих смежные области памяти. При разработке параллельных программ иногда возникает потребность передавать данные разных типов (структуры) или данные, расположенные в несмежных областях памяти (части массивов, не образующих непрерывную последовательность элементов) В MPI предоставляются два механизма эффективной пересылки таких данных: создание производных типов; пересылка упакованных данных.
Упаковка данных (MPI_Pack) Кафедра ЮНЕСКО по НИТ 3 int MPI_Pack (void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, int outcount, int *position, MPI_Comm comm) inbuf адрес начала области памяти с элементами, которые требуется упаковать incount число упаковываемых элементов; datatype тип упаковываемых данных outcount размер выходного буфера в байтах comm коммуникатор position текущая позиция в выходном буфере в байтах Входные параметры: Выходные параметры: outbuf адрес начала выходного буфера для упакованных данных position текущая позиция в выходном буфере в байтах
Упаковка данных (MPI_Pack) Параметр position указывает текущую позицию массива outbuf в байтах, начиная с которой будут размещаться упакованные данные. На выходе из подпрограммы значение position увеличивается на число упакованных байт, указывая на первый свободный байт. Кафедра ЮНЕСКО по НИТ 4 int MPI_Pack (void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, int outcount, int *position, MPI_Comm comm)
Распаковка данных (MPI_Unpack) Кафедра ЮНЕСКО по НИТ 5 int MPI_Unpack (void *inbuf, int insize, int *position, void *outbuf, int outcount,MPI_Datatype datatype, MPI_Comm comm) inbuf адрес начала входного буфера с упакованными данными insize размер входного буфера в байтах position текущая позиция во входном буфере в байтах outcount число извлекаемых элементов datatype тип извлекаемых элементов comm коммуникатор Входные параметры: Выходные параметры: outbuf адрес начала области памяти для размещения распакованных элементов position текущая позиция в выходном буфере в байтах
Сценарий использования упакованных данных Для посылки элементов разного типа из нескольких областей памяти их следует предварительно запаковать в один массив, последовательно обращаясь к функции MPI_Pack. При первом вызове функции упаковки параметр position, устанавливается в 0, чтобы упакованное представление размещалось с начала буфера. В каждом последующем вызове необходимо использовать значение параметра position, полученное из предыдущего вызова. Упакованный буфер пересылается любыми коммуникационными операциями с указанием типа MPI_PACKED и коммуникатора comm, который использовался в MPI_Pack. На принимающей стороне сообщение распаковывается в различные массивы (переменные) последовательными вызовами функции MPI_Unpack с указанием числа элементов, которое следует извлечь при каждом вызове, и с передачей значения position, возвращенного предыдущим вызовом. Очевидно, что для правильной распаковки данных очередность извлечения данных должна быть той же самой, как и при упаковке. Кафедра ЮНЕСКО по НИТ 6
Вычисление минимального размера буфера Кафедра ЮНЕСКО по НИТ 7 int MPI_Pack_size( int incount, MPI_Datatype datatype, MPI_Comm comm, int *size) incount число элементов, подлежащих упаковке datatype тип элементов, подлежащих упаковке comm коммуникатор Входные параметры: Выходные параметры: size размер сообщения в байтах после его упаковки Функция MPI_Pack_size помогает определить размер буфера, необходимый для упаковки некоторого количества данных типа datatype
Пример использования MPI_Status stat; int pos, b, count, my_id, np; float a; char buff[1000]; MPI_Init(…); MPI_Comm_size( MCW, &np); MPI_Comm_rank( MCW, &my_id); if (my_id == 0) { a = 10.0; b = 5; pos = 0; MPI_Pack( &a, 1, MPI_FLOAT, buff, 1000, &pos, MCW); MPI_Pack( &b, 1, MPI_INT, buff, 1000, &pos, MCW); MPI_Send( buff, pos, MPI_PACKED, 1, 333, MCW); } else if (my_id == 1) { MPI_Probe( 0, 333, MCW, &stat); Кафедра ЮНЕСКО по НИТ 8
Пример использования (продолжение) MPI_Get_count( &stat, MPI_PACKED, &count); MPI_Recv( buff, count, MPI_PACKED, 0, 333, MPI_COMM_WORLD, &stat); pos = 0; MPI_Unpack( buff, 1000, &pos, &a, 1, MPI_FLOAT, MPI_COMM_WORLD); MPI_Unpack( buff, 1000, &pos, &b, 1, MPI_INT, MPI_COMM_WORLD); printf(\n my_id = %d, a = %f, b = %d, my_id, a, b); } Кафедра ЮНЕСКО по НИТ 9
10 Задание 1 Создайте и выполните программу, используя функции упаковки и распаковки данных для передачи от нулевого процесса остальным (при помощи MPI_Bcast) двух переменных типа float, массива из трех элементов типа double и одной переменной типа char. Требование: все данные должны передаваться одной широковещательной рассылкой.
Задание 2 Создайте параллельную программу, передающую нечетные элементы одномерного массива типа double длиной с нулевого процесса на первый. Требуется рассмотреть три варианта: передача данных поэлементно, передача массива целиком, упаковка данных перед передачей. Для всех случаев определите время, затрачиваемое на передачу данных. Кафедра ЮНЕСКО по НИТ 11