fdvmPDr (1158423), страница 3
Текст из файла (страница 3)
Директивы INTERVAL и END INTERVAL предназначены для объявления интервалов выполнения программы, на которых пользователь собирается получить характеристики эффективности. Компилятор вставляет в программу обращения к анализатору производительности в начале и в конце каждого интервала:
call binter(...)
. . .
call einter(...)
Если пользователь задал с помощью опции –e режим анализа производительности, тогда в начале и в конце каждого цикла (параллельного и последовательного) компилятор вставляет обращения к функциям анализатора производительности: bploop( ), bsloop( ), и eloop( ).
4.3.8Операторы ввода-вывода
Операторы ввода-вывода, осуществляющие передачу данных, управление и другие вспомогательные операции с внешним файлом, выполняются на одном процессоре (процессоре ввода-вывода), специально выделяемом для этой цели системой поддержки выполнения FDVM программы. Операция ввода-вывода значения размноженной переменной производится над копией переменной, размещенной на процессоре ввода-вывода. Введенное значение рассылается остальным процессорам. Ввод-вывод распределенного массива реализуется с помощью буфера, размещенного на процессоре ввода-вывода. При вводе данные из внешнего файла передаются в буфер, а затем рассылаются тем процессорам, на которые распределен массив. Когда распределенный массив выводится, данные с процессоров, где локализованы элементы массива, сначала пересылаются в буфер, а из буфера передаются во внешний файл.
Компилятор заменяет любой оператор ввода-вывода оператором логический IF:
IF(tstio().NE.0 ) оператор-вввода-вывода
за исключением операторов ввода-вывода во внутренний файл, которые остаются без изменения. Функция tstio( ) возвращает значение 1, если текущий процессор является процессором ввода-вывода.
Для оператора READ, а также любого оператора с управляющим параметром IOSTAT компилятор генерирует обращение к функции srmem( ) для рассылки данных с процессора ввода-вывода на другие процессоры.
При вводе-выводе распределенного массива в программе пользователя выделяется память для буфера ввода-вывода.
Пусть A(N1,N2,...,Nk) – ссылка на распределенный массив размерности k, BUF(L) – вектор того же типа, что и массив A. Тогда компилятор заменит оператор ввода-вывода последовательностью операторов по следующей схеме:
s0 = L
si = [si-1 / Ni] i {1 : k}
n = max( i )
si 0, i{0 : k}
m = 1 (если n = k )
}
DO label In+2 = 0, Nn+2-1. . . n+2 k
DO label Ik = 0, Nk-1
}
DO label In+1 = 0, Nn+1-1, snif (In+1 .LE. Nn+1) then
m = sn n+1 k
else
m = Nn+1 - In+1
endif
ввод:
IF(tstio( ) .ne. 0 ) READ (...) (BUF(j), j = 1, N1 * ...*Nn * m)
| n 1 |
копирование-секции-массива (BUF(1 : N1 * ...*Nn * m),
| n 1 |
A(1: N1,...,1:Nn , In+1 +1: In+1 +m , In+2 +1, ..., Ik +1) )
| n 1 | n+1 k | n+2 k |
вывод:
копирование-секции-массива (BUF(1 : N1 * ...*Nn* m),
| n 1 |
A(1: N1,...,1:Nn , In+1 +1: In+1 +m , In+2 +1, ..., Ik +1) )
| n 1 | n+1 k | n+2 k |
IF(tstio( ) .ne. 0 ) WRITE (...) (BUF(j), j = 1, N1 * ...*Nn * m)
| n 1 |
label CONTINUE
Операция копирования-секции-массива реализуется с помощью функции системы поддержки arrcpy( ).
5Трансляция HPF-DVM программы
5.1Оператор присваивания и другие исполняемые операторы вне цикла INDEPENDENT
HPF-DVM программа выполняется по правилу собственных вычислений. Оператор присваивания
A(I1,I2, ..., IN) = f (B(J1,J2, ..., JK),…)
который встречается вне цикла INDEPENDENT, заменяется на
* копирование элемента распределенного массива
it = rwelmf(B-header,buffer-var,index-array)
. . .
* запрос о том, является ли A(I1,I2, ..., IN) элементом локальной секции
IF(tstelm(A-header,index-array) .NE. 0)
* DVM-reference-A = f(buffer-var,…)
Каждая ссылка на распределенный массив в правой части оператора присваивания, в операторе CALL или в любом другом исполняемом операторе заменяется ссылкой на буферную переменную и для нее генерируется следующий оператор:
* копирование элемента распределенного массива
it = rwelmf(array-header,buffer-var,index-array)
5.2Директива 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)
Блок операторов inquiry-block генерируется только в том случае, если в теле цикла в правых частях операторов присваивания встретились ссылки на распределенные массивы.
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
* включение буфера удаленных элементов в группу
it = insrb(ibg, buffer-header)
* вычисление коэффициентов адресации элементов массива
* NB is rank of buffer array
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















