Lib-DVM - описание интерфейса (оглавление) | Часть 1(1-5) |
Часть 2 (6-7) |
Часть 3 (8-11) |
Часть 4 (12-13) |
Часть 5 (14-15) |
Часть 6 (16-18) |
Часть 7 (19) |
создан: февраль, 2001 | - последнее обновление 03.05.01 - |
14 Регулярный доступ к удаленным данным
Если элементы распределённого массива размещены не на всех процессорах, выполняющих текущую ветвь параллельной программы, где они требуются, то такой массив будем называть удалённым, а его элементы – удалёнными. Доступ к элементам удалённого распределённого массива осуществляется путём создания на каждом процессоре, где требуется и отсутствует хотя бы один из них, специального буфера (локального буфера удалённых элементов) и загрузки в него нужных удалённых данных.
14.1 Создание буфера удалённых элементов распределённого массива
Если ветвью параллельной программы, востребовавшей элементы удалённого массива, является виток параллельного цикла, то будем рассматривать удалённые данные, необходимые для всех его витков, как единое целое.
В этом случае требуемые элементы удалённого распределённого массива определяются с помощью линейных правил выборки (регулярный доступ), задаваемых для каждого его измерения в виде
Ai*Vk(i) + Bi , где:
i | - | номер измерения удалённого распределённого массива; |
Vk(i) | - | индексная переменная k-го измерения параллельного цикла, меняющаяся в пределах своих начального и конечного значений; |
Ai, Bi | - | целые числа. |
Локальные буфера удалённых элементов каждого процессора, выполняющего витки параллельного цикла, рассматриваются как локальные части распределёного массива, который в дальнейшем будем называть глобальным буфером удалённых элементов (или просто буфером удалённых элементов). Буфер удалённых элементов отображён так же, как и параллельный цикл, но его i-му измерению соответствует k(i)-е измерение параллельного цикла (в том случае, когда для i-го измерения удалённого массива задано линейное правило выборки с ненулевым Ai).
В силу приведённых выше правил выборки требуемые удалённые элементы представляются в виде разреженного блока, но помещаются в буфер в уплотнённом (неразреженном) виде.
Работа с буфером удалённых элементов осуществляется аналогично работе с распределённым массивом (см.п.13).
В целях оптимизации буфера удалённых элементов могут объединяться в группы, а загрузка всех буферов группы осуществляться одной операцией (см. п.п. 14.6-14.10).
long crtrbl_ ( | long long void long LoopRef long long long |
RemArrayHeader[], BufferHeader[], *BasePtr, *StaticSignPtr, *LoopRefPtr, AxisArray[], CoeffArray[], ConstArray[] ); |
RemArrayHeader | - | заголовок удалённого распределённого массива. | ||
BufferHeader | - | заголовок создаваемого буфера удалённых элементов. | ||
BasePtr | - | базовый указатель для доступа к буферу удалённых элементов. | ||
*StaticSignPtr | - | признак создания статического буфера. | ||
*LoopRefPtr | - | ссылка на параллельный цикл, при выполнении которого необходимы размещённые в буфере элементы удалённого массива. | ||
AxisArray | - | массив, i-й элемент которого содержит номер измерения параллельного цикла (k(i+1)), соответствующего (i+1)-му измерению удалённого массива. | ||
CoeffArray | - | массив, i-й элемент которого содержит коэффициент индексной переменной линейного правила выборки для (i+1)-го измерения удалённого массива (Ai+1). | ||
ConstArray | - | массив, i-й элемент которого содержит константу линейного правила выборки для (i+1)-го измерения удалённого массива (Bi+1). |
Функция crtrbl_ создаёт буфер для размещения в нём элементов удалённого распределённого массива с заголовком RemArrayHeader, необходимых для выполнения параллельного цикла, заданного ссылкой *LoopRefPtr. Удалённый массив должен быть отображён в процессорную систему, каждый элемент которой принадлежит текущей процессорной системе. Цикл на момент обращения к функции должен быть текущим и отображённым.
Созданный буфер является распределённым массивом, размерность которого меньше размерности удалённого массива на число константных линейных правил выборки удалённых элементов. Его заголовок BufferHeader представляет собой массив из 2*r+2 элементов типа "long", где r – размерность буфера (расширенный заголовок распределённого массива, см. п. 13.4). Размещение заголовка в памяти (статическое или динамическое) осуществляется пользовательской программой, а инициализация - системой поддержки при выполнении функции crtrbl_ .
В любом i-м элементе массива AxisArray может быть задан либо номер измерения параллельного цикла, либо 0, либо –1. В первом случае CoeffArray[i] должен быть ненулевым (неконстантное правило выборки). Во втором случае CoeffArray[i] обязан быть нулевым (константное правило выборки). Наконец, третий случай определяет свободное (i+1)-е измерение удалённого массива, т. е. не связанное ни с каким измерением параллельного цикла ("присутствующее везде").
Таким образом, размерность буфера удалённых элементов равна числу ненулевых элементов массива AxisArray. Размер каждого j-го измерения буфера определяется значением j-го по счёту ненулевого элемента массива AxisArray (пусть индекс этого элемента будет i). Если AxisArray[i] > 0 (линейное правило выборки), то размер j-го измерения буфера равен размеру (AxisArray[i])-го измерения заданного параллельного цикла (размер измерения цикла в данном случае – увеличенное на единицу абсолютное значение разности между начальным и конечным значениями индексной переменной измерения). Если же AxisArray[i] = -1 (свободное измерение удалённого массива), то размер j-го измерения буфера совпадает с размером (i+1)-го измерения удалённого массива.
В массиве AxisArray не может быть задано два одинаковых номера измерения параллельного цикла.
Число элементов в каждом из массивов AxisArray, CoeffArray и ConstArray должно быть равно размерности удалённого распределённого массива.
Корректно заданные правила выборки не должны выводить за пределы удалённого распределённого массива.
Базовый указатель BasePtr должен ссылаться на любую переменную, имеющую тот же тип, что и элементы удалённого распределённого массива. Содержимое этой переменной несущественно, т.к. базовый указатель используется только для доступа к удалённым элементам распределённого массива, размещённым в создаваемом буфере.
Подробнее работа с заголовком буфера удалённых элементов и базовым указателем рассмотрена в п.14.5.
Задаваемый ненулевым значением *StaticSignPtr признак статического буфера означает создание буфера, не уничтожаемого при выходе из программного блока (см.п.8). Такой буфер может быть уничтожен только явно, с помощью рассмотренной ниже функции delrb_ .
Функция возвращает ненулевое значение, если созданный буфер имеет локальную часть на текущем процессоре, и нулевое – в противном случае.
Замечание 1. Если все правила выборки являются константами, то размерность создаваемого буфера, в силу изложенного выше, должна быть равной нулю. В этом случае система поддержки создаёт одномерный распределённый массив-буфер, состоящий из одного элемента.
Замечание 2. Пусть при отображении параллельного цикла функцией mappl_ по какому-либо его измерению начальное значение индексной переменной, при положительном шаге, больше её конечного значения или, при отрицательном шаге, конечное значение индексной переменной больше её начального значения (пустой цикл). Тогда использование этого цикла в качестве параметра функции crtrbl_ приведёт к созданию фиктивного буфера удалённых элементов. 0-му слову заголовка такого буфера (ссылке на распределённый массив) будет присвоено нулевое значение. Фиктивный буфер удалённых элементов может использоваться во всех функциях организации удалённого доступа, но использование его заголовка в качестве параметра функций работы с распределёнными массивами запрещено. Не допускается также доступ к локальной части распределённого массива по заголовку фиктивного буфера.
Буфер удалённых элементов, необходимых для выполнения параллельного цикла, а также для ветвей программы, не являющихся его витками, может быть создан также с помощью рассмотренных ниже функций crtrba_ и crtrbp_.
long crtrba_ ( | long long void long long long long long |
RemArrayHeader[], BufferHeader[], *BasePtr, *StaticSignPtr, LocArrayHeader[], AxisArray[], CoeffArray[], ConstArray[] ); |
RemArrayHeader | - | заголовок удалённого распределённого массива. | ||
BufferHeader | - | заголовок создаваемого буфера удалённых элементов. | ||
BasePtr | - | базовый указатель для доступа к буферу удалённых элементов. | ||
*StaticSignPtr | - | признак создания статического буфера. | ||
LocArrayHeader | - | заголовок распределённого массива (локального), при обработке которого необходимы размещённые в буфере элементы удалённого массива. | ||
AxisArray | - | массив i-й элемент которого содержит номер измерения локального распределённого массива, соответствующего (i+1)-му измерению удалённого массива (k(i+1), см. ниже). | ||
CoeffArray | - | массив, i-й элемент которого содержит коэффициент индексной переменной линейного правила выборки для (i+1)-го измерения удалённого массива (Ai+1, см. ниже). | ||
ConstArray | - | массив, i-й элемент которого содержит константу линейного правила выборки для (i+1)-го измерения удалённого массива (Bi+1. см. ниже). |
Функция crtrba_ создаёт буфер для размещения в нём элементов удалённого распределённого массива с заголовком RemArrayHeader, необходимых для работы с распределённым массивом (локальным), заданным заголовком LocArrayHeader. Удалённый и локальный распределённые массивы должны быть отображены в процессорные системы (возможно, каждый в свою), все элементы которых принадлежат текущей процессорной системе.
Требуемые элементы удалённого распределённого массива задаются для каждого его измерения, не являющегося свободным, с помощью линейных правил выборки:
Ai*Vk(i) + Bi , где:
i | - | номер измерения удалённого распределённого массива; |
Vk(i) | - | индексная переменная k-го измерения локального распределённого массива, меняющаяся в пределах своих начального и конечного значений; |
Ai | - | целое число; |
Bi | - | целое неотрицательное число. |
Буфер удалённых элементов, создаваемый функцией crtrba_, отображён так же, как и локальный распределённый массив, но его i-му измерению соответствует k(i)-е измерение локального массива (в том случае, когда для i-го измерения удалённого массива задано линейное правило выборки с ненулевым Ai).
Все параметры функции crtrba_ (кроме LocArrayHeader) аналогичны одноимённым параметрам рассмотренной ранее функции crtrbl_.
Функция возвращает ненулевое значение, если созданный буфер имеет локальную часть на текущем процессоре, и нулевое – в противном случае.
long crtrbp_ ( | long long void long PSRef long |
RemArrayHeader[], BufferHeader[], *BasePtr, *StaticSignPtr, *PSRefPtr, CoordArray[] ); |
RemArrayHeader | - | заголовок удалённого распределённого массива. | ||
BufferHeader | - | заголовок создаваемого буфера удалённых элементов. | ||
BasePtr | - | базовый указатель для доступа к буферу удалённых элементов. | ||
*StaticSignPtr | - | признак создания статического буфера. | ||
*PSRefPtr | - | ссылка на процессорную систему, на каждом процессоре которой необходимо присутствие элементов удалённого распределённого массива. | ||
CoordArray | - | массив, i-й элемент которого содержит значение координаты требуемого элемента по (i+1)-му измерению удалённого массива. |
Функция crtrbp_ создаёт буфер для размещения в нём элементов удалённого распределённого массива с заголовком RemArrayHeader, присутствие которых необходимо на каждом процессоре системы, заданной ссылкой *PSRefPtr.
Удалённый распределённый массив должен быть отображён в процессорную систему, все элементы которой обязаны принадлежать текущей процессорной системе. Ссылкой *PSRefPtr может быть определена текущая процессорная система или её непосредственная или косвенная подсистема. Равное NULL значение указателя PSRefPtr или нулевое значение ссылки *PSRefPtr задают текущую процессорную систему.
Требуемые элементы удалённого распределённого массива задаются для каждого его (i+1)-го измерения значением i-го слова массива CoordArray: неотрицательное значение определяет координату элемента удалённого массива; отрицательное значение задаёт всё измерение удалённого массива (аналог свободного измерения удалённого массива в описании функций crtrbl_ и crtrba_). Число элементов в массиве CoordArray должно быть равно размерности удалённого распределённого массива.
Размерность буфера удалённых элементов, создаваемого функцией crtrbp_, равна числу отрицательных элементов массива CoordArray. Размер каждого j-го измерения буфера равен размеру измерения удалённого массива, соответствующего j-му по счёту отрицательному элементу массива CoordArray. Если все элементы массива CoordArray неотрицательны (задан ровно один удалённый элемент), то система поддержки создаёт одномерный распределённый массив-буфер, состоящий из одного элемента.
При выполнении функции crtrbp_ буфер удалённых элементов отображается таким образом, чтобы все требуемые и, следовательно, размещённые в нём элементы присутствовали на всех процессорах системы, заданной параметром PSRefPtr. Для этого система поддержки создаёт вспомогательное одномерное представление текущей абстрактной машины, состоящее из одного элемента, и отображает его в заданную при обращении к функции процессорную систему с размножением по всем её измерениям. Буфер удалённых элементов отображается, в свою очередь, во вспомогательное представление с размножением по его единственному измерению.
Функция возвращает ненулевое значение, если созданный буфер имеет локальную часть на текущем процессоре, и нулевое – в противном случае.
14.2 Запуск загрузки буфера удаленных элементов распределенного массива
long loadrb_ ( | long long |
BufferHeader[], *RenewSignPtr ); |
BufferHeader | - | заголовок буфера удалённых элементов. | ||
*RenewSignPtr | - | признак повторной перезагрузки уже загруженного буфера. |
Функция loadrb_ инициирует загрузку заданного буфера элементами распределённого массива, для которых этот буфер был создан с помощью функций crtrbl_, crtrba_ или crtrbp_.
Допускается использование функции для уже загруженного буфера. В этом случае фактическая перезагрузка осуществляется при ненулевом значении параметра *RenewSignPtr и не осуществляется, если его значение равно нулю. Запрещается перезагрузка буфера (вне зависимости от значения параметра *RenewSignPtr), если его предыдущая загрузка (фактическая или фиктивная) не завершена с помощью функции waitrb_ (см. п. 14.3).
Как загружаемый буфер, так и его удалённый распределённый массив должны быть отображены в процессорные системы, каждый элемент которых обязан принадлежать текущей процессорной системе.
Не допускается запуск загрузки буфера функцией loadrb_, если он включён в какую-либо группу буферов (см. п.п. 14.6-14.10).
Возвращается нулевое значение.
14.3 Ожидание завершения загрузки буфера удаленных элементов распределенного массива
long waitrb_ (long BufferHeader[]);
BufferHeader - заголовок буфера удалённых элементов.
Загрузка заданного при обращении к функции буфера должна быть инициирована текущей подзадачей. Не допускается ожидание завершения не инициированной ранее загрузки буфера.
Возвращается нулевое значение.
14.4 Уничтожение буфера удаленных элементов распределенного массива
long delrb_ (long BufferHeader[]);
BufferHeader - заголовок уничтожаемого буфера удалённых элементов.
Буфер удалённых элементов может быть уничтожен функцией delrb_ только в том случае, если он был создан в текущей подзадаче и в текущем программном блоке (или его подблоке) (см. п. 8 и п. 10).
Буфер удалённых элементов может быть уничтожен также с помощью функции delobj_ (см.п.17.5).
Не доспускается уничтожение буфера, загрузка которого не завершена с помощью функции waitrb_.
Если уничтожаемый буфер включён в какую-либо группу буферов, то он из состава этой группы исключается (см. п.п. 14.6-14.10). Группа буферов в этом случае не должна находиться в состоянии загрузки.
Возвращается нулевое значение.
14.5 Доступ к размещенным в локальной части буфера удаленным элементам
Пусть r – размерность буфера (число измерений удалённого распределённого массива, имеющих неконстантные линейные правила выборки или являющихся свободными). Тогда заголовок буфера удалённых элементов, задаваемый при обращении к функции crtrbl_ (crtrba_, crtrbp_), может быть объявлен, например, как
long BufferHeader[2*r+2];
Пусть также базовый указатель, соответствующий типу элементов удалённого распределённого массива, есть BasePtr. Тогда обращение к размещённому в локальной части буфера удалённому элементу, определённому индексным вектором (I1, ... , Im, ... , Ir), осуществляется по линейному индексу следующим образом:
Для языка C при обращении к функциям crtrbl_, crtrba_ и crtrbp_ значение базового указателя можно задать равным NULL. Тогда доступ к размещённому в локальной части буфера удалённому элементу можно произвести разименованно:
где Type - тип элементов удалённого распределённого массива.
Для буфера удалённых элементов, созданного функцией crtrbl_.
Пусть измерение буфера m соответствует линейному правилу выборки удалённых элементов (связанное измерение) и, следовательно, некоторому измерению параллельного цикла k. Тогда при доступе к элементу буфера значение координаты Im может быть заменено значением индексной переменой цикла Vk: Im = Vk – min(Vk,нач , Vk,кон) (Vk,нач и Vk,кон – начальное и конечное значения индексной переменной цикла Vk). Это означает, что переход из индексного пространства буфера в индексное пространство параллельного цикла влечёт переход к распределёному массиву-буферу с ненулевыми нижними границами индексов. Поэтому в целях поддержки доступа к элементам буфера по индексным переменным цикла система поддержки при выполнении функции crtrbl_ для всех связанных измерений сохраняет в заголовке буфера величины min(Vk,нач , Vk,кон) в качестве нижних границ измерений массива (см. описание расширенного заголовка распределённых массивов в п. 13.4). Нижние границы свободных измерений буфера устанавливаются в его заголовке нулевыми.
В языке C для доступа к элементам буфера по индексным переменным параллельного цикла могут быть использованы макрокоманды вида
<RBElmType> RBElm<Rank> ( | long long . . . . long |
BufferHeader[], <RBElmType>, Index1, . . . . . . . . . . Index<Rank> ); |
BufferHeader | - | заголовок буфера удалённых элементов. | ||
Rank | - | размерность буфера (1-7). | ||
RBElmType | - | тип элементов, размещённых в буфере. | ||
Indexi | - | значение индекса требуемого элемента для i-го измерения буфера. |
Семь вышеописанных макрокоманд являются L-выражениями языка C.
Предполагается, что при создании буфера с помощью функции crtrbl_ базовый указатель был задан равным NULL.
14.6 Создание группы буферов удаленных элементов
RegularAccessGroupRef crtbg_( | long long |
*StaticSignPtr, *DelBufSignPtr ); |
*StaticSignPtr | - | признак создания статической группы буферов. | ||
*DelBufSignPtr | - | признак уничтожения всех буферов, входящих в группу, при её уничтожении. |
Функция crtbg_ создает пустую группу буферов (не содержащую ни одного буфера) и возвращает ссылку на неё.
Задаваемый ненулевым значением *StaticSignPtr признак статической группы означает создание группы, не уничтожаемой при выходе из программного блока (см.п.8). Такая группа может быть уничтожена только явно, с помощью рассмотреной ниже функции delbg_ .
Ненулевое значение *DelBufSignPtr задает такой режим уничтожения группы буферов, при котором все входящие в неё буфера будут также уничтожены. При явном уничтожении группы уничтожение входящих в неё буферов будет также считаться явным, при неявном - неявным.
14.7 Включение в группу буфера удаленных элементов
long insrb_ ( | RegularAccessGroupRef long |
*RegularAccessGroupRefPtr, BufferHeader[] ); |
*RegularAccessGroupRefPtr | - | ссылка на группу буферов. | ||
BufferHeader | - | заголовок включаемого буфера. |
Как группа буферов, так и включаемый в неё буфер должны быть созданы в текущей подзадаче и не могут находиться в состоянии загрузки. Допускается повторное включение буфера в группу, но нельзя включить буфер в группу буферов, если он уже включён в другую группу.
Возвращается нулевое значение.
14.8 Запуск загрузки буферов удаленных элементов заданной группы
long loadbg_( | RegularAccessGroupRef long |
*RegularAccessGroupRefPtr, *RenewSignPtr ); |
*RegularAccessGroupRefPtr | - | ссылка на группу буферов. | ||
*RenewSignPtr | - | признак повторной перезагрузки уже загруженной группы буферов. |
Все буфера заданной при обращении к функции группы и их удалённые распределённые массивы должны быть отображены в процессорные системы, каждый элемент которых принадлежит текущей процессорной системе.
Допускается использование функции loadbg_ для уже загруженной группы буферов. В этом случае фактическая перезагрузка осуществляется при ненулевом значении параметра *RenewSignPtr и не осуществляется, если его значение равно нулю. Запрещается перезагрузка группы буферов (вне зависимости от значения параметра *RenewSignPtr), если её предыдущая загрузка (фактическая или фиктивная) не завершена с помощью функции waitbg_ (см. п. 14.9).
Возвращается нулевое значение.
14.9 Ожидание завершения загрузки буферов удаленных элементов заданной группы
long waitbg_ (RegularAccessGroupRef *RegularAccessGroupRefPtr);
*RegularAccessGroupRefPtr - ссылка на группу буферов.
Загрузка заданной при обращении к функции группы буферов должна быть запущена текущей подзадачей. Не допускается ожидание завершения не инициированной ранее загрузки группы буферов.
Возвращается нулевое значение.
14.10 Уничтожение группы буферов удаленных элементов
long delbg_ (RegularAccessGroupRef *RegularAccessGroupRefPtr);
*RegularAccessGroupRefPtr - ссылка на уничтожаемую группу буферов.
Группа буферов удалённых элементов может быть уничтожена функцией delbg_ только в том случае, если она была создана в текущей подзадаче и в текущем программном блоке (или его подблоке) (см. п. 8 и п. 10).
Группа буферов может быть уничтожена также с помощью функции delobj_ (см.п.17.5).
Не допускается уничтожение группы буферов, загрузка которой не завершена с помощью функции waitbg_.
Если группа буферов была создана функцией crtbg_ с ненулевым значением параметра *DelBufSignPtr, то при её уничтожении будут уничтожены и все включённые в неё буфера удалённых элементов.
Возвращается нулевое значение.
14.11 Опрос типа доступа к элементам распределенного массива
long rmkind_ ( | long long void long LoopRef long long long long long |
ArrayHeader[], BufferHeader[], *BasePtr, *StaticSignPtr, *LoopRefPtr, AxisArray[], CoeffArray[], ConstArray[], LowShdWidthArray[], HiShdWidthArray[] ); |
ArrayHeader | - | заголовок распределённого массива. | ||
BufferHeader | - | заголовок создаваемого буфера удалённых элементов (для доступа типа "REMOTE"). | ||
BasePtr | - | базовый указатель для доступа к буферу удалённых элементов (для доступа типа "REMOTE"). | ||
*StaticSignPtr | - | признак создания статического буфера (для доступа типа "REMOTE"). | ||
*LoopRefPtr | - | ссылка на параллельный цикл, при выполнении которого необходимы элементы распределённого массива. | ||
AxisArray | - | массив i-й элемент которого содержит номер измерения параллельного цикла, соответствующего (i+1)-му измерению распределённого массива. |
CoeffArray | - | массив, i-й элемент которого содержит коэффициент индексной переменной линейного правила выборки для (i+1)-го измерения распределённого массива. | ||
ConstArray | - | массив, i-й элемент которого содержит константу линейного правила выборки для (i+1)-го измерения распределённого массива. | ||
LowShdWidthArray | - | выходной массив, в i-й элемент которого будет записана ширина нижней границы (i+1)-го измерения распределённого массива (для доступа типа "SHADOW" или "FULL SHADOW"). | ||
HiShdWidthArray | - | выходной массив, в i-й элемент которого будет записана ширина верхней границы (i+1)-го измерения распределённого массива (для доступа типа "SHADOW" или "FULL SHADOW"). |
Функция rmkind_ определяет тип доступа к элементам распределённого массива с заголовком ArrayHeader, необходимым для выполнения параллельного цикла, заданного ссылкой *LoopRefPtr.
Требуемые для выполнения цикла элементы массива задаются аналогично заданию элементов удалённого массива, необходимых для выполнения параллельного цикла (см. п. 14.1). Параметры BufferHeader, BasePtr, StaticSignPtr, AxisArray, CoeffArray и ConstArray аналогичны одноимённым параметрам функции crtrbl_.
Распределённый массив должен быть отображён в процессорную систему, каждый элемент которой принадлежит текущей процессорной системе. Параллельный цикл на момент обращения к функции должен быть текущим и отображённым.
Тип доступа кодируется следующими возвращаемыми функцией значениями:
1 - локальный
доступ;
2 - доступ
типа "SHADOW";
3 - доступ
типа "FULL SHADOW";
4 - доступ
типа "REMOTE" (удалённый доступ).
Тип доступа утанавливается следующим образом. Пусть PS - процессорная система, в которую отображён заданный параллельный цикл. Тогда:
Если доступ имеет тип "SHADOW" или "FULL SHADOW", то в массивы LowShdWidthArray и HiShdWidthArray записываются ширины границ распределённого массива, заданные при его создании.
В случае удалённого доступа функция rmkind_, обращаясь к функции crtrbl_, создаёт буфер удалённых элементов с заголовком BufferHeader.
15 Нерегулярный доступ к удаленным данным
Схема нерегулярного доступа к элементам удалённого распределённого массива аналогична рассмотренной в п.14 схеме регулярного доступа, но область её применения ограничена массивами, имеющими только одно распределённое измерение (остальные измерения размножены). Необходимые для выполнения параллельного цикла и размещаемые в буфере элементы удалённого массива задаются множеством индексных векторов вида
где:
n | - | размерность удалённого массива; |
k | - | номер его распределённого измерения; |
C1, ... , Ck-1, Ck+1, … , Cn | - | координаты размноженных измерений удалённого массива (целые неотрицательные числа); |
ME | - | матрица глобальных индексов (или индексная матрица); |
Vk , J | - | индексные переменные правила выборки координат распределённого (k-го) измерения удалённого массива; |
Vk,нач , Vk,кон | - | начальное и конечное значения индексной переменной Vk. |
Индексная матрица ME представляет собой двухмерный распределённый массив типа "integer", первое измерение которого распределено, а второе размножено. Здесь и далее будем считать распределённый массив размноженным по измерению i, если значение многозначной функции отображения этого массива F( (I1, …, Ii, …, In) ) не зависит от значения Ii (см. п.7.1). Размер первого измерения индексной матрицы MESize1 обычно (но не обязательно) равен размеру распределённого (k-го) измерения удалённого массива. Размер MESize2 второго измерения матрицы ME равен
MAX(ME[Vk,0])
+ 1 .
0 <= Vk < MESize1
Смысл элементов индексной матрицы:
ME[Vk,0] | - | число соответствующих переменной Vk координат распределённого измерения удалённого массива; |
ME[Vk,J+1] | - | для каждых Vk и J: значение координаты распределённого измерения удалённого массива (0 <= J < ME[Vk,0]). |
15.1 Создание буфера удаленных элементов нерегулярного доступа
long crtibl_ ( | long long void long LoopRef long long |
RemArrayHeader[], BufferHeader[], *BasePtr, *StaticSignPtr, *LoopRefPtr, MEHeader[], ConstArray[] ); |
RemArrayHeader | - | заголовок удалённого распределённого массива. | ||
BufferHeader | - | заголовок создаваемого буфера удалённых элементов. | ||
BasePtr | - | базовый указатель для доступа к буферу удалённых элементов. | ||
*StaticSignPtr | - | признак создания статического буфера. | ||
*LoopRefPtr | - | ссылка на одномерный параллельный цикл, при выполнении которого необходимы размещённые в буфере элементы удалённого массива. | ||
MEHeader | - | заголовок индексной матрицы. | ||
ConstArray | - | массив, i-й элемент которого содержит значение константы выборки элементов для (i+1)-го измерения удалённого распределённого массива (Ci+1). |
Функция crtibl_ создаёт буфер для размещения в нём элементов удалённого распределённого массива с заголовком RemArrayHeader, необходимых для выполнения одномерного параллельного цикла, заданного ссылкой *LoopRefPtr.
Удалённый массив должен быть отображён в процессорную систему, каждый элемент которой принадлежит текущей процессорной системе. Он должен иметь единственное распределённое измерение (остальные размножены).
Заданный параллельный цикл на момент обращения к функции должен быть текущим и отображённым. Его индексной переменной является рассмотренная ранее переменная Vk правила выборки координат распределённого измерения удалённого массива. Начальное и конечное значения переменной Vk (Vk,нач и Vk,кон) не могут быть отрицательными или превосходить уменьшенный на единицу размер первого измерения индексной матрицы.
Созданный буфер является двухмерным распределённым массивом, первое измерение которого распределено так же, как измерение (единственное) заданного параллельного цикла, а второе - размножено. Длина первого измерения буфера равна увеличенному на единицу абсолютному значению разности между конечным и начальным значениями индексной переменной Vk заданного параллельного цикла, а длина второго совпадает с уменьшенной на единицу длиной второго измерения индексной матрицы.
Заголовок буфера BufferHeader представляет собой массив из 6-и элементов типа "long" (расширенный заголовок распределённого массива, см. п. 13.4). Размещение заголовка в памяти (статическое или динамическое) осуществляется пользовательской программой, а инициализация - системой поддержки при выполнении функции crtibl_ .
Работа с буфером удалённых элементов осуществляется аналогично работе с распределённым массивом (см.п.13).
В целях оптимизации буфера удалённых элементов могут объединяться в группы, а загрузка всех буферов группы осуществляться одной операцией (см. п.п. 15.6 - 15.10).
Базовый указатель BasePtr должен ссылаться на любую переменную, имеющую тот же тип, что и элементы удалённого распределённого массива. Содержимое этой переменной несущественно, т.к. базовый указатель используется только для доступа к удалённым элементам распределённого массива, размещённым в созданном буфере.
Подробнее работа с заголовком буфера удалённых элементов и базовым указателем рассмотрена в п.15.5.
Заголовок индексной матрицы MEHeader представляет собой массив из 3-х или 6-и элементов типа "long" (стандартный или расширенный заголовок распределённого массива, см. п. 13.4). На момент обращения к функции crtibl_ индексная матрица должна быть отображена в процессорную систему, каждый элемент которой обязан принадлежать текущей процессорной системе. Первое измерение индексной матрицы должно быть распределено так же, как измерение заданного параллельного цикла (с точностью до коэффициента линейного правила отображения), а второе - размножено. Ширины нижних и верхних границ, заданные при создании индексной матрицы, должны быть нулевыми.
Число элементов в массиве ConstArray должно быть равно размерности удалённого распределённого массива. Значение ConstArray[k-1] несущественно (k - номер распределённого измерения удалённого массива).
Задаваемый ненулевым значением *StaticSignPtr признак статического буфера означает создание буфера, не уничтожаемого при выходе из программного блока (см.п.8). Такой буфер может быть уничтожен только явно, с помощью рассмотренной ниже функции delib_ (см. п. 15.4).
Функция возвращает ненулевое значение, если созданный буфер имеет локальную часть на текущем процессоре, и нулевое – в противном случае.
Замечание. Пусть при отображении заданного параллельного цикла функцией mappl_ начальное значение индексной переменной Vk, при положительном шаге, больше её конечного значения или, при отрицательном шаге, конечное значение индексной переменной Vk больше её начального значения (пустой цикл). Тогда использование этого цикла в качестве параметра функции crtibl_ приведёт к созданию фиктивного буфера удалённых элементов. 0-му слову заголовка такого буфера (ссылке на распределённый массив) будет присвоено нулевое значение. Фиктивный буфер удалённых элементов может использоваться во всех функциях организации удалённого доступа, но использование его заголовка в качестве параметра функций работы с распределёнными массивами запрещено. Не допускается также доступ к локальной части распределённого массива по заголовку фиктивного буфера.
Буфер удалённых элементов нерегулярного доступа может быть также создан с помощью функции
long crtib_ ( | long long void long long long |
RemArrayHeader[], BufferHeader[], *BasePtr, *StaticSignPtr, MEHeader[], ConstArray[] ); |
Функция crtib_ отличается от рассмотренной ранее функции crtibl_ отсутствием параметра LoopRefPtr, задающего ссылку на параллельный цикл. Созданный буфер будет распределён по обоим измерениям так же, как заданная индексная матрица. Размер его первого измерения будет совпадать с размером первого измерения индексной матрицы, а размер второго на единицу меньше размера второго измерения индексной матрицы.
Функция crtib_ позволяет создать буфер и запустить его загрузку (см. п. 15.2) до создания и отображения параллельного цикла, при выполнении которого будут использоваться помещённые в буфер элементы удалённого распределённого массива.
15.2 Запуск загрузки буфера удаленных элементов нерегулярного доступа
long loadib_ ( | long long |
BufferHeader[], *RenewSignPtr ); |
BufferHeader | - | заголовок буфера удалённых элементов. | ||
*RenewSignPtr | - | признак повторной перезагрузки уже загруженного буфера. |
Функция loadib_ инициирует загрузку заданного буфера элементами распределённого массива, для которых этот буфер был создан функцией crtibl_ (или crtib_).
Допускается использование функции для уже загруженного буфера. В этом случае фактическая перезагрузка осуществляется при ненулевом значении параметра *RenewSignPtr и не осуществляется, если его значение равно нулю. Запрещается перезагрузка буфера (вне зависимости от значения параметра *RenewSignPtr), если его предыдущая загрузка (фактическая или фиктивная) не завершена с помощью функции waitib_ (см. п. 15.3).
Как загружаемый буфер, так и его удалённый распределённый массив должны быть отображены в процессорные системы, каждый элемент которых обязан принадлежать текущей процессорной системе.
Не допускается запуск загрузки буфера функцией loadib_, если он включён в какую-либо группу буферов (см. п.п. 15.6 - 15.10).
Возвращается нулевое значение.
15.3 Ожидание завершения загрузки буфера удаленных элементов нерегулярного доступа
long waitib_ (long BufferHeader[]);
BufferHeader - заголовок буфера удалённых элементов нерегулярного доступа.
Загрузка заданного при обращении к функции буфера должна быть инициирована текущей подзадачей. Не допускается ожидание завершения не инициированной ранее загрузки буфера.
Возвращается нулевое значение.
15.4 Уничтожение буфера удаленных элементов нерегулярного доступа
long delib_ (long BufferHeader[]);
BufferHeader - заголовок уничтожаемого буфера удалённых элементов.
Буфер удалённых элементов может быть уничтожен функцией delib_ только в том случае, если он был создан в текущей подзадаче и в текущем программном блоке (или его подблоке) (см. п. 8 и п. 10).
Буфер удалённых элементов нерегулярного доступа может быть уничтожен также с помощью функции delobj_ (см.п.17.5).
Не доспускается уничтожение буфера, загрузка которого не завершена с помощью функции waitib_.
Если уничтожаемый буфер включён в какую-либо группу буферов, то он из состава этой группы исключается (см. п.п. 15.6 - 15.10). Группа буферов в этом случае не должна находиться в состоянии загрузки.
Возвращается нулевое значение.
15.5 Доступ к размещенным в буфере удаленным элементам
Буфер удалённых элементов нерегулярного доступа является двухмерным распределённым массивом с расширенным заголовком. Поэтому его заголовок может быть объявлен, например, как
long BufferHeader[6];
Пусть базовый указатель, соответствующий типу элементов удалённого распределённого массива, есть BasePtr. Тогда обращение к размещённому в локальной части буфера удалённому элементу, определённому индексным вектором (I1, I2), осуществляется следующим образом:
BasePtr[ BufferHeader[1]*I1 + I2 + BufferHeader[2] ] .
Для языка C при обращении к функции crtibl_ (или crtib_) значение базового указателя можно задать равным NULL. Тогда доступ к размещённому в буфере удалённому элементу можно осуществить разименованно:
( (Type *)BufferHeader[2] )[ BufferHeader[1]*I1 + I2 ] ,
где Type - тип элементов удалённого распределённого массива.
Доступ к элементам буфера по индексной переменной параллельного цикла.
1-е измерение буфера удалённых элементов соответствует 1-му (и единственному) измерению параллельного цикла, при выполнении которого требуются размещённые в буфере элементы (см. п. 15.1). Поэтому значение координаты I1 может быть заменено на значение индексной переменой цикла Vk (k - номер распределённого измерения удалённого массива): I1 = Vk – min(Vk,нач , Vk,кон) (Vk,нач и Vk,кон – начальное и конечное значения индексной переменной цикла Vk). Это означает, что переход из индексного пространства буфера в индексное пространство параллельного цикла влечёт переход к распределёному массиву-буферу с ненулевой нижней границей индекса по 1-му измерению. Поэтому в целях поддержки доступа к элементам буфера по индексной переменной цикла система поддержки при выполнении функции crtibl_ сохраняет в BufferHeader[4] величину min(Vk,нач , Vk,кон) в качестве нижней границы 1-го измерения массива (см. описание расширенного заголовка распределённых массивов в п. 13.4).
Если буфер создаётся функцией crtib_, то элементу заголовка BufferHeader[4] присваивается нулевое значение.
Нижняя граница 2-го (размноженного) измерения буфера устанавливается в его заголовке (в BufferHeader[5]) равной единице. Это означает, что координате J второго измерения индексной матрицы будет соответствовать координата J-1 второго измерения буфера.
В языке C для доступа к элементам буфера по индексной переменной параллельного цикла может быть использована макрокоманда RBElm2 (см. п. 14.5). При обращении к макрокоманде RBElm2 в качестве Index2 задаётся значение индексной переменной второго измерения индексной матрицы.
15.6 Создание группы буферов удаленных элементов нерегулярного доступа
IndirectAccessGroupRef crtig_ ( | long long |
*StaticSignPtr, *DelBufSignPtr ); |
*StaticSignPtr | - | признак создания статической группы буферов. | ||
*DelBufSignPtr | - | признак уничтожения всех буферов, входящих в группу, при её уничтожении. |
Функция crtig_ создает пустую группу буферов (не содержащую ни одного буфера) и возвращает ссылку на неё.
Задаваемый ненулевым значением *StaticSignPtr признак статической группы означает создание группы, не уничтожаемой при выходе из программного блока (см.п.8). Такая группа может быть уничтожена только явно, с помощью рассмотреной ниже функции delig_ .
Ненулевое значение *DelBufSignPtr задает такой режим уничтожения группы буферов, при котором все входящие в неё буфера будут также уничтожены. При явном уничтожении группы уничтожение входящих в неё буферов будет также считаться явным, при неявном - неявным.
15.7 Включение в группу буфера удаленных элементов нерегулярного доступа
long insib_ ( | IndirectAccessGroupRef long |
*IndirectAccessGroupRefPtr, BufferHeader[] ); |
*IndirectAccessGroupRefPtr | - | ссылка на группу буферов. | ||
BufferHeader | - | заголовок включаемого буфера. |
Как группа буферов, так и включаемый в неё буфер должны быть созданы в текущей подзадаче и не могут находиться в состоянии загрузки. Допускается повторное включение буфера в группу, но нельзя включить буфер в группу буферов, если он уже включён в другую группу.
Возвращается нулевое значение.
15.8 Запуск загрузки буферов удаленных элементов заданной группы
long loadig_( | IndirectAccessGroupRef long |
*IndirectAccessGroupRefPtr, *RenewSignPtr ); |
*IndirectAccessGroupRefPtr | - | ссылка на группу буферов. | ||
*RenewSignPtr | - | признак повторной перезагрузки уже загруженной группы буферов. |
Все буфера заданной при обращении к функции группы и их удалённые распределённые массивы должны быть отображены в процессорные системы, каждый элемент которых принадлежит текущей процессорной системе.
Допускается использование функции loadig_ для уже загруженной группы буферов. В этом случае фактическая перезагрузка осуществляется при ненулевом значении параметра *RenewSignPtr и не осуществляется, если его значение равно нулю. Запрещается перезагрузка группы буферов (вне зависимости от значения параметра *RenewSignPtr), если её предыдущая загрузка (фактическая или фиктивная) не завершена с помощью функции waitig_ (см. п. 15.9).
Возвращается нулевое значение.
15.9 Ожидание завершения загрузки буферов удаленных элементов заданной группы
long waitig_ (IndirectAccessGroupRef *IndirectAccessGroupRefPtr);
*IndirectAccessGroupRefPtr - ссылка на группу буферов.
Загрузка заданной при обращении к функции группы буферов должна быть запущена текущей подзадачей. Не допускается ожидание завершения не инициированной ранее загрузки группы буферов.
Возвращается нулевое значение.
15.10 Уничтожение группы буферов удаленных элементов нерегулярного доступа
long delig_ (IndirectAccessGroupRef *IndirectAccessGroupRefPtr);
*IndirectAccessGroupRefPtr - ссылка на уничтожаемую группу буферов.
Группа буферов удалённых элементов может быть уничтожена функцией delig_ только в том случае, если она была создана в текущей подзадаче и в текущем программном блоке (или его подблоке) (см. п. 8 и п. 10).
Группа буферов может быть уничтожена также с помощью функции delobj_ (см.п.17.5).
Не допускается уничтожение группы буферов, загрузка которой не завершена с помощью функции waitig_.
Если группа буферов была создана функцией crtig_ с ненулевым значением параметра *DelBufSignPtr, то при её уничтожении будут уничтожены и все включённые в неё буфера удалённых элементов.
Возвращается нулевое значение.