fdvmDDr (1158419), страница 7
Текст из файла (страница 7)
массива, которые вычисляются как линейная функция элементов
заголовка массива
base - i0000m , если A имеет тип integer
r0000m , если A имеет тип real
d0000m , если A имеет тип double precision
c0000m , если A имеет тип complex
l0000m , если A имеет тип logical
5.4.2Цикл INDEPENDENT
void IndependentLoop ( SgStatement *stmt )
| stmt | - указатель на директиву INDEPENDENT |
Тесно-гнездовой цикл INDEPENDENT:
*HPF$ INDEPENDENT
DO label I1 = ...
. . .
*HPF$ INDEPENDENT
DO label In = ...
тело-цикла
label CONTINUE
транслируется в:
* создание параллельного цикла
ipl = crtpl(n)
* отображение параллельного цикла
it = mappl(ipl,...)
[ inquiry-block ]
* запрос о продолжении выполнения параллельного цикла
lab1 if(dopl(ipl) .eq. 0) go to lab2
DO label I1 = ...
. . .
DO label In = ...
тело-цикла
label CONTINUE
go to lab1
* завершение параллельного цикла
lab2 it = endpl(ipl)
Функция генерирует и вставляет в процедуру те операторы, которые предшествуют гнезду циклов DO, за исключением блока inquiry-block. Кроме того, заменяются начальное значение, конечное значение и шаг do-переменных гнезда циклов DO. Операторы, следующие за последним оператором параллельного цикла генерируются функцией TransFunc( ) в момент его обработки. Блок inquiry-block формируется функцией RemoteVariableListIND( ).
Если задан отладочный режим компиляции, то генерируются операторы CALL :
call dbegpl(...)
call diter(...)
call dendl(...)
которые вставляются в блок (2) перед оператором IF, перед первым оператором тела параллельного цикла и вслед за оператором
go to lab1
, соответственно.
Если задан режим компиляции для анализа производительности, то генерируются операторы CALL:
call bploop(...)
call eloop(...)
которые вставляются перед первым и вслед за последним оператором блока (2).
void IndependentLoop_Debug ( SgStatement *stmt )
| stmt | - указатель на директиву INDEPENDENT |
Если задан отладочный режим компиляции, то генерируются операторы CALL :
call dbegpl(...)
call diter(...)
которые вставляются перед гнездом циклов DO и перед первым оператором тела параллельного цикла, соответственно.
Если задан режим компиляции для анализа производительности, то генерируются операторы CALL:
call bploop(...)
call eloop(...)
которые вставляются перед и после гнезда циклов.
void RemoteVariableListIND ( )
Если в правых частях операторов присваивания в теле цикла INDEPENDENT встречаются ссылки на элементы распределенных массивов, то генерируется следующий блок операторов:
ishg = 0
ibg = 0
{
* запрос о типе доступа к элементам распределенного массива
kind = rmkind(array-header,buffer-header,…,
* low-shadow-array,high-shadow-array)
IF (kind .EQ. 4) THEN
IF (ishg .EQ. 0) THEN
* создание группы буферов удаленных данных
ibg = crtbg(0,1)
ENDIF
* включение буферного массива в группу RMG
it = insrb(ibg, buffer-header)
* вычисление коэффициентов адресации элементов буферного массива
* NB – размерность буферного массива
header-copy(1) = buffer-header(2)
. . .
header-copy(NB-1) = buffer-header(NB)
header-copy(NB) = 1
header-copy(NB+1) = buffer-header(NB+1)-
* buffer-header(NB)*buffer-header(NB+3) … -
* buffer-header(3)*buffer-header(2*NB+2)
ELSE
IF (kind .NE. 1) THEN
IF (ishg .EQ. 0) THEN
* создание группы теневых граней
ishg = crtshg(0)
ENDIF
* включение теневой грани в группу
* (с угловыми элементами или без)
IF (kind .EQ. 2) THEN
it = inssh(ishg,array-header,low-shadow-array,
* high-shadow-array,0)
ELSE
it = inssh(ishg,array-header,low-shadow-array,
* high-shadow-array,1)
ENDIF
* вычисление коэффициентов адресации элементов массива
header-copy(1) = f1(array-header,IkN)
. . .
header-copy(NB) = f1(array-header,Ik1)
header-copy(NB+1) = f2(buffer-header(2:N+1),I1,…,IN)
ENDIF
}... для каждой удаленной ссылки внутри тела цикла
* обновление теневых граней группы ishg
IF (ishg .NE. 0) THEN
it = strtsh(ishg)
it = waitsh(ishg)
ENDIF
* загрузка буферов группы ibg
IF (ibg .NE. 0) THEN
it = loadbg(ibg,1)
it = waitbg(ibg)
ENDIF
Этот блок (inquiry-block) вставляется перед первым оператором DO гнезда циклов INDEPENDENT.















