Теория и практика параллельных вычислений

       

Понятие производного типа данных


В самом общем виде под производным типом данных в MPI можно понимать описание набора значений предусмотренного в MPI типа, причем в общем случае описываемые значения не обязательно непрерывно располагаются в памяти. Задание типа в MPI принято осуществлять при помощи карты типа (type map) в виде последовательности описаний входящих в тип значений; каждое отдельное значение описывается указанием типа и смещения адреса месторасположения от некоторого базового адреса, т.е.

TypeMap = {(type0, disp0),...,(typen-1, dispn-1)}.

Часть карты типа с указанием только типов значений именуется в MPI сигнатурой типа:

TypeSignature = {type0,...,typen-1}.

Сигнатура типа описывает, какие базовые типы данных образуют некоторый производный тип данных MPI, и, тем самым, управляет интерпретацией элементов данных при передаче или получении сообщений. Смещения карты типа определяют, где находятся значения данных.

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

double a; /* адрес 24 */ double b; /* адрес 40 */ int n; /* адрес 48 */

Тогда производный тип для описания таких данных должен иметь карту типа следующего вида:

{(MPI_DOUBLE, 0), (MPI_DOUBLE, 16), (MPI_INT, 24)}

Дополнительно для производных типов данных в MPI используется следующий ряд новых понятий:

  • нижняя граница типа ;
  • верхняя граница типа ;
  • протяженность типа .

Согласно определению, нижняя граница есть смещение для первого байта значений рассматриваемого типа данных. Соответственно, верхняя граница представляет собой смещение для байта, располагающегося вслед за последним элементом рассматриваемого типа данных. При этом величина смещения для верхней границы может быть округлена вверх с учетом требований выравнивания адресов. Так, одно из требований, которые налагают некоторые реализации языков C и Fortran, состоит в том, чтобы адрес элемента был кратен длине этого элемента в байтах. Например, если тип int занимает четыре байта, то адрес элемента типа int должен нацело делиться на четыре.
Именно это требование и отражается в определении верхней границы типа данных MPI. Поясним данный момент на ранее рассмотренном примере набора переменных a, b и n, для которого нижняя граница равна 0, а верхняя принимает значение 32 (величина округления 6 или 4 в зависимости от размера типа int). Здесь следует отметить, что требуемое выравнивание определяется по типу первого элемента данных в карте типа.

Следует также указать на различие понятий "протяженность" и "размер типа". Протяженность – это размер памяти в байтах, который нужно отводить для одного элемента производного типа. Размер типа данных – это число байтов, которые занимают данные (разность между адресами последнего и первого байтов данных). Различие в значениях протяженности и размера опять же в величине округления для выравнивания адресов. Так, в рассматриваемом примере размер типа равен 28, а протяженность – 32 (предполагается, что тип int занимает четыре байта).

Для получения значения протяженности типа в MPI предусмотрена функция:

int MPI_Type_extent(MPI_Datatype type, MPI_Aint *extent),

где

  • type — тип данных, протяженность которого отыскивается;
  • extent — протяженность типа.


Размер типа можно найти, используя функцию:

int MPI_Type_size(MPI_Datatype type, MPI_Aint *size),

где

  • type — тип данных, размер которого отыскивается;
  • size — размер типа.


Определение нижней и верхней границ типа может быть выполнено при помощи функций:

int MPI_Type_lb(MPI_Datatype type, MPI_Aint *disp) и int MPI_Type_ub(MPI_Datatype type, MPI_Aint *disp),

где

  • type — тип данных, нижняя граница которого отыскивается;
  • disp — нижняя/верхняя граница типа.


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

int MPI_Address(void *location, MPI_Aint *address),

где

  • location — адрес памяти;
  • address — адрес памяти в переносимом MPI-формате


(следует отметить, что данная функция является переносимым вариантом средств получения адресов в алгоритмических языках C и Fortran).


Содержание раздела