2017-01-14 1 views
0

Или вопрос можно перефразировать следующим образом: Зачем нужен тип данных с ненулевой нижней границей?Почему у нас есть нижняя и верхняя границы для типов данных в MPI?

Рассмотрим следующий пример:

struct S { 
    int a; 
    int b; 
    float c; 
    float d; 
} array[N]; 

Если бы я был массив типа S[], и я хотел послать только значения полей b и d, я бы создать datatype с типом карты { (4, MPI_INT), (12, MPI_FLOAT) }. Во-первых, кажется, что такой тип может быть использован, чтобы правильно отправить массив struct S:

MPI_Send(array, N, datatype, ...); 

Но это не работает, если N > 1. Такой тип имел бы lb = 4, ub = 16 и extent = ub - lb = 12. То есть, MPI будет считать, что второй элемент массива запускает 12 байтов из первого , что неверно.

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

MPI_Type_create_resized(datatype, 0, sizeof(struct S), &resized); 

Но я удивляюсь, почему мы всегда должны указать нулевой нижней границы. Зачем кому-то нужна ненулевая нижняя граница? Типы данных с ненулевыми нижними границами выглядят чрезвычайно запутанными для меня, и я не могу их понять.

Если бы я планировал создать систему типов для MPI, я бы описал тип с единственным параметром - его размером (протяженностью), который является шагом между двумя соседними элементами массива. Что касается MPI, я бы всегда задавал lb = 0 и extent = ub. Такая система выглядит намного яснее для меня, и она будет работать правильно в описанном выше примере.

Но MPI выбрал другой способ. У нас есть два независимых параметров: нижний и верхние границы. Почему это так? Какая польза от этой дополнительной гибкости? Когда следует использовать типы данных с ненулевой нижней границей?

ответ

0

Вы не представляете, какие странные и сложные структуры можно найти в научных и технических кодексах. The standard разработан как можно более общий и обеспечивает максимальную гибкость. Раздел 4.1.6 Нижняя граница и Верхняя Скованные Маркеры начинается так:

Часто бывает удобно определить в явном виде нижней границы и верхней границы карты типа, и переопределить определение, данное на стр 105 Это позволяет определить тип данных, который имеет «дыры» в начале или конце, или тип данных с элементами, которые выходят за верхнюю границу или ниже нижней границы. Примеры такого использования приведены в разделе 4.1.14. Кроме того, пользователь может захотеть переопределить [sic] правила выравнивания, которые используются для вычисления верхних границ и экстентов. Например, компилятор C может разрешить пользователю переопределять [sic] правила выравнивания по умолчанию для некоторых структур внутри программы.Пользователь должен явно указывать границы типов данных, которые соответствуют этим структурам.

Простейшим примером типа данных с ненулевой нижней границей представляет собой структуру с абсолютными адресами, используемыми в виде смещений, полезных, например, в отправке структур с указателями на данных, разбросанных в памяти. Такой тип данных используется с MPI_BOTTOM, указанным в качестве адреса буфера, который соответствует нижней части памяти (0 на большинстве систем). Если нижняя граница будет зафиксирована на 0, вам необходимо найти элемент данных с наименьшим адресом и вычислить все смещения относительно него.

Другим примером является использование MPI_Type_create_subarray для создания типа данных, который описывает подмассиву n-мерного массива. С нулевыми нижними границами вам нужно будет указать указатель на начало подмассива. С ненулевыми нижними границами вы просто указываете на начало всего массива. И вы также можете создать непрерывный тип данных таких типов данных subarray, чтобы отправить такие n-мерные «срезы» из n + 1-мерного массива.

+0

Извините, но ваш ответ на самом деле ничего не объясняет. 1) Я просмотрел стандарт и нашел несколько примеров с MPI_Type_create_resized. Однако ни один из примеров не использовал ненулевой фунт. 2) Я не понял вашу часть MPI_BOTTOM. Структура, которую вы описали, по своей сути является единственной в своем роде. У вас никогда не будет такого массива таких структур. Таким образом, для такого типа данных имеет значение только тип карты, в то время как границы вообще не имеют значения. 3) MPI_Type_create_subarray создает тип данных с lb = 0. – Nikolai

+0

1) Примеры, приведенные в стандарте, не являются исчерпывающими. Допустимое использование типов с отрицательным LB предназначено для обработки массивов Fortran с отрицательными индексами, например. 'INTEGER A (-5: 5)'. 2) LB типа - это только минимальное смещение в типовой карте, если явный маркер LB не был помещен с использованием 'MPI_Type_create_resized'. MPI не используется для отправки только массивов. 3) Этот истинный LB типов данных, созданных с помощью 'MPI_Type_create_subarray', когда субарейк не начинается в начале массива, отличен от нуля. Он помещает явные привязанные маркеры, как и в вашем примере. –

+0

Вы не * имеете * использовать '0' как LB в вызове' MPI_Type_create_resized'. Это вполне справедливо: 'MPI_Type_get_extent (тип данных, & lb, & extent); MPI_Type_create_resized (тип данных, lb, sizeof (struct S) и измененный размер); 'и' resized' будут иметь ненулевой LB и будут по-прежнему использоваться для отправки массивов 'struct S'. LB '0' используется для удобства, поскольку упрощает вычисление смещений в большинстве случаев при дальнейшем объединении типов данных. Это то, что делает конструктор subarray, и поэтому в типах данных их LB явно установлен в '0'. –

Смежные вопросы