Московский государственный университет путей сообщения
Опубликован: 22.12.2006 | Доступ: свободный | Студентов: 2440 / 570 | Оценка: 4.07 / 4.02 | Длительность: 16:07:00
ISBN: 978-5-9556-0071-0
Специальности: Разработчик аппаратуры
Лекция 11:

Программирование задач для асинхронной ВС архитектуры "data flow"

< Лекция 10 || Лекция 11: 12345 || Лекция 12 >

Операторы цикла

Задача параллельного выполнения операторов цикла может решаться посредством либо распараллеливания по итерациям, либо распараллеливания операторов внутри тела цикла. Распараллеливание по итерациям может быть применено для распределения групп повторений тела цикла по процессорам ПВС. Распараллеливание же внутри тела цикла может производиться так же, как и для последовательности операторов.

Определим оператор цикла типа арифметической прогрессии следующим образом:

<оператор цикла типа арифметической прогрессии> ::=

for <параметр цикла> := A1 step A2 until A3 do S

В этом определении A1, A2, A3 — арифметические выражения, а S — оператор (тело цикла).

В ПВС может быть использован подход, аналогичный "раскрутке" циклов.

Оператор цикла транслируется в программу коммутации, схема которой имеет вид, представленный на рис. 11.9.

Программа цикла

Рис. 11.9. Программа цикла

Команды 1 \div  k-1 соответствуют вычислению значений арифметических выражений A1, A2 и A3, если они не являются константами или именами переменных. Команда k — организация цикла (ЦИКЛ), команда N — конец цикла (КЦ).

Между командами ЦИКЛ и КЦ расположены команды, соответствующие телу цикла S. Эта часть программы коммутации образуется по правилам трансляции соответствующей конструкции языка. В частности, если тело цикла — оператор присваивания (последовательность операторов присваивания), то трансляция его происходит по приведенному алгоритму.

Программа коммутации выполняется следующим образом. Сначала коммутируется выполнение команд вычисления значений a1, a2, a3 выражений A1, A2 и A3. Команда ЦИКЛ засылает в регистр счетчика цикла (СЦ) число повторений цикла:

\begin{align*}
p = \frac{a3 - a1 +1}{a2}
\end{align*}

Далее осуществляется коммутация выполнения команд, составляющих тело цикла S. Если в теле цикла отсутствуют операторы перехода за границы цикла, то при обработке процессором команды КЦ содержимое регистра СЦ уменьшается на единицу. В случае неравенства его нулю коммутация продолжается с первой команды тела цикла. В противном случае далее коммутируется выполнение команды N+1, следующей за командой КЦ. Таким образом, осуществляется непрерывная коммутация всего цикла, что обеспечивает возможность параллельного выполнения команд тела цикла.

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

for i := 1 step 1 until 5 do
  begin
    x := a[i];
    R[i] := x x b;
    Q[i] := x / b;
  end

все итерации фактически будут выполняться последовательно, поскольку образуется очередь заявок к памяти на запись и считывание из ячейки с адресом x. В то же время очевидно, что информационно итерации друг с другом не связаны, поэтому можно добиться их параллельного выполнения, применив переименование переменных. Переменная х заменяется на x[i], компоненту массива x [1...5]. Цикл принимает вид

for i := 1 step 1 until 5 do
  begin
    x[i] := a[i];
    R[i] := x[i] x b;
    Q[i] := x[i] / b;
  end

Теперь все пять его итераций могут выполняться одновременно.

Очень важно, что при асинхронном выполнении итераций не возникает ошибок, которые связаны с нарушением порядка вычислений, предписываемого логическими связями между переменными. Рассмотрим следующий цикл

for i := 1 step 1 until 2 do
  begin
    x[i] := a[i];
    R[i] := x[i] x b;
    R[i + 1] := x[i] / b;
    print (R[i], R[i + 1]);
  end

Все вычисления в обеих итерациях могут выполняться независимо друг от друга и одновременно. Правильная же работа операторов печати гарантирована тем, что команды программы коммутации обрабатываются процессором последовательно и заявки на запись и считывание к ячейке, в которой должно находиться значение R[2], выдаваемые при коммутации выполнения первой и второй итераций, будут упорядочены.

При трансляции операторов цикла итерационного типа,

<оператор цикла итерационного типа> ::= for <параметр цикла>
    := A1;A2 while B do S,

где A1, A2 — арифметические выражения, B — логическое выражение, S — оператор, образуется программа коммутации, содержащая команду условного перехода.

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

< Лекция 10 || Лекция 11: 12345 || Лекция 12 >