Jump to content

Анализ зависимости цикла

В информатике с анализ зависимостей цикла — это процесс, который можно использовать для поиска зависимостей внутри итераций цикла целью определения различных отношений между операторами. Эти зависимые отношения связаны с порядком, в котором различные операторы обращаются к областям памяти. Используя анализ этих взаимосвязей, можно организовать выполнение цикла так, чтобы несколько процессоров могли работать над разными частями цикла параллельно. Это известно как параллельная обработка . В общем, циклы могут занимать много времени обработки при выполнении в виде последовательного кода . Благодаря параллельной обработке можно сократить общее время выполнения программы за счет распределения вычислительной нагрузки между несколькими процессорами.

Процесс организации операторов, позволяющий нескольким процессорам работать над разными частями цикла, часто называют распараллеливанием . Чтобы увидеть, как мы можем использовать распараллеливание, нам нужно сначала проанализировать зависимости внутри отдельных циклов. Эти зависимости помогут определить, какие инструкции в цикле необходимо выполнить, прежде чем смогут начаться другие инструкции, и какие инструкции в цикле могут выполняться параллельно по отношению к другим инструкциям в цикле. Две общие категории зависимостей, которые будут анализироваться в цикле, — это зависимости данных и зависимости управления .

Описание

[ редактировать ]

Анализ зависимости цикла происходит на нормализованном цикле вида:

for i1 until U1 do
  for i2 until U2 do
    ...
    for in until Un do
      body
    done
    ...
  done
done

где тело может содержать:

S1  a[f1(i1, ..., in), ..., fm(i1, ..., in)] := ...
    ...
S2  ... := a[h1(i1, ..., in), ..., hm(i1, ..., in)]

Где a — m-мерный массив и ж н , час н и т. д. — это функции, отображающие все индексы итерации (i n ) на доступ к памяти в определенном измерении массива.

Например, в С:

for (i = 0; i < U1; i++)
  for (j = 0; j < U2; j++)
    a[i+4-j] = b[2*i-j] + i*j;

f 1 будет я+4-дж , управление записью в первом измерении a и h 2 будет 2*идж , управляя чтением по первому измерению b .

Задача состоит в том, чтобы найти все возможные зависимости между S1 и S2 . Чтобы быть консервативным, любую зависимость, ложность которой невозможно доказать, следует считать истинной.

Независимость демонстрируется путем демонстрации того, что никакие два экземпляра S1 и S2 не получают доступ или не изменяют одно и то же место в массиве. а . Когда обнаруживается возможная зависимость, анализ циклической зависимости обычно делает все возможное, чтобы охарактеризовать отношения между зависимыми экземплярами, поскольку некоторые оптимизации все еще могут быть возможны. Также возможно преобразовать цикл, чтобы удалить или изменить зависимость.

В ходе доказательства или опровержения таких зависимостей утверждение S может быть декомпозировано в зависимости от того, из какой итерации оно получено. Например, S [1,3,5] относится к итерации, где я1 = 1 , я2 = 3 и я3 = 5 . Конечно, ссылки на абстрактные итерации, такие как S [ d1 +1, d2 , d3 ], разрешены и распространены.

Зависимость данных

[ редактировать ]

Зависимости данных показывают отношения между переменными в коде. Существует три различных типа зависимостей данных:

  • Истинная зависимость (иногда называемая зависимостью от потока)
  • Антизависимость
  • Выходная зависимость

Истинная зависимость

[ редактировать ]

Настоящая зависимость возникает, когда ячейка памяти записывается до того, как она будет прочитана. [1] [2] [3] Это создает опасность чтения после записи (RAW), поскольку инструкция, выполняющая чтение из ячейки памяти, должна ждать, пока в нее не будет записана предыдущая инструкция, иначе инструкция чтения прочитает неправильное значение. [2] Пример истинной зависимости:

S1: a = 5;
S2: b = a;

В этом примере существует истинная зависимость между S1 и S2, поскольку переменная a сначала записывается в операторе S1, а затем переменная a считывается оператором S2. Эту истинную зависимость можно представить как S1 →T S2. Истинную зависимость также можно увидеть при чтении и записи между различными итерациями в цикле. Следующий пример показывает истинную зависимость между различными итерациями.

for (j = 1; j < n; j++)
    S1: a[j] = a[j-1];

В этом примере существует истинная зависимость между утверждением S1 на j-й итерации и S1 на j+1-й итерации. Существует истинная зависимость, поскольку значение будет записано в a[j] на одной итерации, а затем произойдет чтение с помощью a[j-1] на следующей итерации. Эту истинную зависимость можно представить как S1[j] →T S1[j+1].

Антизависимость

[ редактировать ]

Антизависимость возникает , когда ячейка памяти считывается до того, как в нее записывается. [1] [2] [3] Это создает опасность записи после чтения (WAR), поскольку инструкция, записывающая данные в ячейку памяти, должна ждать, пока эта ячейка памяти не будет прочитана предыдущей инструкцией, иначе инструкция чтения прочитает неправильное значение. [2] Пример антизависимости:

S1: a = b;
S2: b = 5;

В этом примере существует антизависимость между утверждениями S1 и S2. Это антизависимость, поскольку переменная b сначала считывается в операторе S1, а затем в переменную b записывается в операторе S2. Это можно представить как S1 →A S2. Антизависимость можно увидеть по различным итерациям цикла. В следующем примере показан пример этого случая:

for (j = 0; j < n; j++)
    S1: b[j] = b[j+1];

В этом примере существует антизависимость между j-й итерацией S1 и j+1-м элементом S1. Здесь j+1-й элемент считывается до того, как тот же элемент будет записан в следующей итерации j. Эту антизависимость можно представить как S1[j] →A S1[j+1].

Выходная зависимость

[ редактировать ]

Зависимость вывода возникает, когда ячейка в памяти записывается до того, как эта же ячейка будет записана снова в другом операторе. [1] [2] [3] Это создает опасность записи после записи (WAW) , поскольку вторая инструкция для записи значения в ячейку памяти должна ждать, пока первая инструкция не завершит запись данных в ту же ячейку памяти, или в противном случае, когда ячейка памяти будет прочитана позже. он будет содержать неправильное значение. [2] Пример выходной зависимости:

S1: c = 8; 
S2: c = 15;

В этом примере существует зависимость вывода между операторами S1 и S2. Здесь переменная c сначала записывается в S1, а затем снова записывается в переменную c в операторе S2. Эту зависимость выхода можно представить как S1 →O S2. Выходную зависимость можно увидеть по различным итерациям цикла. В следующем фрагменте кода показан пример этого случая:

for (j = 0; j < n; j++) {
    S1: c[j] = j;  
    S2: c[j+1] = 5;
}

В этом примере существует выходная зависимость между j-м элементом в S1 и j+1-м элементом в S2. Здесь c[j+1] в операторе S2 записывается за одну итерацию. На следующей итерации снова записывается c[j] в операторе S2, который находится в той же ячейке памяти, что и c[j+1] в предыдущей итерации. Эту выходную зависимость можно представить как S1[j] →O S2[j+1].

Зависимость от управления

[ редактировать ]

Зависимости управления также необходимо учитывать при анализе зависимостей между различными операторами в цикле. Зависимости управления — это зависимости, вносимые кодом или самим алгоритмом программирования. Они контролируют порядок, в котором инструкции выполняются при выполнении кода. [4] Одним из распространенных примеров является оператор «if». Операторы «if» создают ветки в программе. Часть «then» оператора «if» явно указывает или контролирует действия, которые необходимо предпринять. [3]

// Code block 1 (CORRECT)
if (a == b) {
   c = "controlled";
}
d = "uncontrolled";
// Code block 2 (INCORRECT)
if (a == b) {
}
c = "controlled";
d = "uncontrolled";
// Code block 3 (INCORRECT)
if (a == b) {
   c = "controlled";
   d = "uncontrolled";
}

В этом примере проиллюстрированы ограничения на поток управления. Блок кода 1 показывает правильный порядок использования оператора if в языке программирования C. Блок кода 2 иллюстрирует проблему, когда оператор, который должен управляться оператором if, больше не контролируется им. Блок кода 3 иллюстрирует проблему, когда оператор, который не должен контролироваться оператором «if», теперь перешел под его контроль. Обе эти две возможности могут привести к неправильному выполнению программы и их следует учитывать при распараллеливании этих операторов внутри цикла.

Зависимость, переносимая в цикле, и зависимость, независимая от цикла

[ редактировать ]

Зависимости, переносимые циклом, и зависимости, независимые от цикла, определяются отношениями между операторами в итерациях цикла. Когда оператор в одной итерации цикла каким-то образом зависит от оператора в другой итерации того же цикла, существует зависимость, переносимая циклом. [1] [2] [3] Однако если оператор в одной итерации цикла зависит только от оператора в той же итерации цикла, это создает независимую от цикла зависимость. [1] [2] [3]

// Code block 1
for (i = 1; i <= 4; i++) {
   S1: b[i] = 8;
   S2: a[i] = b[i-1] + 10;
}
// Code block 2
for (i = 0; i < 4; i++) {
   S1: b[i] = 8;
   S2: a[i] = b[i] + 10;
}

В этом примере блок кода 1 показывает зависимую от цикла зависимость между итерацией i оператора S2 и итерацией i-1 оператора S1. Это означает, что оператор S2 не может продолжаться до тех пор, пока не завершится оператор S1 на предыдущей итерации. Блок кода 2 показывает независимую от цикла зависимость между операторами S1 и S2 в одной итерации.

Циклическая зависимость и графы обхода итерационного пространства

[ редактировать ]

Графы обхода пространства итераций (ITG) показывают путь, который проходит код при прохождении итераций цикла. [1] Каждая итерация представлена ​​узлом. Графы зависимостей, переносимые циклом (LDG), дают визуальное представление всех истинных зависимостей, антизависимостей и выходных зависимостей, которые существуют между различными итерациями в цикле. [1] Каждая итерация представлена ​​узлом.

Разницу между двумя графиками проще показать с помощью вложенного цикла for.

 for (i = 0; i < 4; i++)
    for (j = 0; j < 4; j++)
       S1: a[i][j] = a[i][j-1] * x;

В этом примере существует истинная зависимость между j-й итерацией оператора S1 и j+1-м оператором S1. Это можно представить как S1[i,j] →T S1[i,j+1] Граф обхода итерационного пространства и график зависимости, переносимый циклом: Граф обхода итерационного пространства: График зависимости, переносимый циклом:

График зависимости с циклическим переносом (LDG)
Граф обхода итерационного пространства (ITG)


См. также

[ редактировать ]
  1. ^ Jump up to: а б с д и ж г Солихин, Ян (2016). Основы параллельной компьютерной архитектуры: многокристальные и многоядерные системы . [США?]: Солихин Паб. ISBN  978-1-4822-1118-4 .
  2. ^ Jump up to: а б с д и ж г час Деван, Прадип; Камат, РК (2014). «Обзор — анализ зависимостей LOOP для распараллеливающего компилятора». Международный журнал компьютерных наук и информационных технологий . 5 .
  3. ^ Jump up to: а б с д и ж Джон, Хеннесси; Паттерсон, Дэвид (2012). «Глава третья, параллелизм на уровне инструкций и его использование». Архитектура компьютера. Количественный подход . Издательство Морган Кауфманн. стр. 152–156. ISBN  978-0-12-383872-8 .
  4. ^ Аллен-младший; Кеннеди, Кен; Портерфилд, Кэрри; Уоррен, Джо (1 января 1983 г.). «Преобразование зависимости управления в зависимость данных». Материалы 10-го симпозиума ACM SIGACT-SIGPLAN по принципам языков программирования - POPL '83 . ПОПЛ '83. Нью-Йорк, штат Нью-Йорк, США: ACM. стр. 177–189. дои : 10.1145/567067.567085 . ISBN  0897910907 . S2CID   39279813 .
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: a30ebb9590852b13f8ee1cb16c3d4e51__1709899380
URL1:https://arc.ask3.ru/arc/aa/a3/51/a30ebb9590852b13f8ee1cb16c3d4e51.html
Заголовок, (Title) документа по адресу, URL1:
Loop dependence analysis - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)