Jump to content

Параллелизм уровня петли

Параллелизм уровня петли является формой параллелизма в программном программировании , которая связана с извлечением параллельных задач из петлей . Возможность параллелизма уровня петли часто возникает в вычислительных программах, где данные хранятся в случайного доступа структурах данных . В тех случаях, когда последовательная программа будет выполнять структуру данных и работать по индексам по одному, в программе, использующей параллелизм уровня петли, будет использовать несколько потоков или процессов , которые работают на некоторых или всех индексах одновременно. Такой параллелизм обеспечивает ускорение общего времени выполнения программы, обычно в соответствии с законом Амдала .

Описание

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

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

Рассмотрим следующий код, работающий в списке L длины n.

for (int i = 0; i < n; ++i) {
    S1: L[i] += 10;
}

Каждая итерация цикла берет значение из текущего индекса L, и увеличивает это на 10. Если оператор S1 принимает T Время для выполнения, тогда цикл требует времени n * T Чтобы выполнить последовательно, игнорируя время, принятое конструкциями петли. Теперь рассмотрим систему с p процессоры, где p > nПолем Если n потоки работают параллельно, время для выполнения всех n шаги уменьшаются до T.

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

for (int i = 1; i < n; ++i) {
    S1: L[i] = L[i-1] + 10;
}

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

Зависимости в коде

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

Есть несколько типов зависимостей, которые можно найти в коде. [ 1 ] [ 2 ]

Тип Обозначение Описание
Истинная (поток) зависимость S1 ->T S2 Истинная зависимость между S1 и S2 означает, что S1 пишет в местоположении, которое позже читается от S2
Анти -зависимость S1 ->A S2 Антизазапада между S1 и S2 означает, что S1 читает из места, позже написанного S2.
Выходная зависимость S1 ->O S2 Выходная зависимость между S1 и S2 означает, что S1 и S2 записываются в то же место.
Входная зависимость S1 ->I S2 Входная зависимость между S1 и S2 означает, что S1 и S2 читаются из того же места.

Чтобы сохранить последовательное поведение петли при запуске параллельно, истинная зависимость должна быть сохранена. Антизазазависимость и зависимость выходной сигналы можно решать, предоставив каждому процессу свою собственную копию переменных (известных как приватизация). [ 1 ]

Пример истинной зависимости

[ редактировать ]
S1: int a, b;
S2: a = 2;
S3: b = a + 40;

S2 ->T S3, это означает, что S2 имеет истинную зависимость от S3, потому что S2 пишет с переменной a, который S3 читает от.

Пример антизависимости

[ редактировать ]
S1: int a, b = 40;
S2: a = b - 38;
S3: b = -1;

S2 ->A S3, это означает, что S2 обладает антизависимостью на S3, потому что S2 считывается из переменной b Перед S3 пишет это.

Пример зависимости от вывода

[ редактировать ]
S1: int a, b = 40;
S2: a = b - 38;
S3: a = 2;

S2 ->O S3, это означает, что S2 имеет выходную зависимость от S3, потому что оба записывают в переменную a.

Пример входной зависимости

[ редактировать ]
S1: int a, b, c = 2;
S2: a = c - 1;
S3: b = c + 1;

S2 ->I S3, это означает, что S2 имеет входную зависимость от S3, потому что S2 и S3 считываются из переменной c.

Зависимость в петлях

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

Зависимость от петли против зависящей от петли

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

Петли могут иметь два типа зависимости:

  • Зависимость от петли
  • Зависимость от петли

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

В следующем примере кода, используемого для обмена значениями двух массива длины n, существует независимая от цикла зависимости S1 ->T S3.

for (int i = 1; i < n; ++i) {
    S1: tmp = a[i];
    S2: a[i] = b[i];
    S3: b[i] = tmp;
}

В зависимости от петли заявления в итерации цикла зависят от утверждений в другой итерации цикла. Зависимость, получающая петлю, использует модифицированную версию обозначения зависимости, которую можно увидеть ранее.

Пример зависимости от петли, где S1[i] ->T S1[i + 1], где i указывает на текущую итерацию и i + 1 Указывает следующую итерацию.

for (int i = 1; i < n; ++i) {
    S1: a[i] = a[i-1] + 1;
}

Цикл переноса графика зависимости

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

Графически графический график зависимости зависимости от петли показывает зависимости от итераций между итерациями. Каждая итерация указана как узел на графике, а направленные ребра показывают истинные зависимости и выходные данные между каждой итерацией.

Существует множество методологий для параллельных петлей.

  • Распределенная петля
  • Долл Параллелизм
  • Докросс параллелизм
  • Спираль [ 3 ]
  • Параллелизм Dopipe

Каждая реализация немного зависит от того, как синхронизируются потоки, если вообще. Кроме того, параллельные задачи должны быть каким -то образом нанесены на карту с процессом. Эти задачи могут быть выделены статически или динамически. Исследования показали, что балансировка нагрузки может быть лучше достигнута с помощью некоторых алгоритмов динамического распределения, чем при выполнении статически. [ 4 ]

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

Тип Описание
Разложение Программа разбита на задачи, самую маленькую эксплуатационную единицу согласия.
Назначение Задачи назначены процессам.
Оркестровка Доступ к данным, связь и синхронизация процессов.
Картирование Процессы связаны с процессорами.

Распределенная петля

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

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

for (int i = 1; i < n; ++i) {
    S1: a[i] = a[i-1] + b[i];
    S2: c[i] += d[i];
}

Цикл имеет петлю, несущую зависимость S1[i] ->T S1[i+1] Но S2 и S1 не имеют независимой от цикла зависимости, поэтому мы можем переписать код следующим образом.

loop1: for (int i = 1; i < n; ++i) {
    S1: a[i] = a[i-1] + b[i];
}
loop2: for (int i = 1; i < n; ++i) {
    S2: c[i] += d[i];
}

Обратите внимание, что теперь Loop1 и Loop2 могут быть выполнены параллельно. Вместо отдельной инструкции выполняются параллельно на разных данных, как в параллелизме уровня данных, здесь разные петли выполняют разные задачи на разных данных. Допустим, время исполнения S1 и S2 будет и тогда время выполнения для последовательной формы вышеупомянутого кода составляет , Теперь, потому что мы разделили два утверждения и размещаем их в двух разных петлях, дает нам время исполнения Полем Мы называем этот тип параллелизма либо функции, либо параллелизмом задачи.

Долл Параллелизм

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

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

for (int i = 0; i < n; ++i) {
    S1: a[i] = b[i] + c[i];
}

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

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

begin_parallelism();
for (int i = 0; i < n; ++i) {
    S1: a[i] = b[i] + c[i];
    end_parallelism();
}
block();

Докросс параллелизм

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

Параллелизм Doacross существует там, где итерации петли параллелизируются путем извлечения расчетов, которые можно выполнять независимо и выполнять их одновременно. [ 5 ]

Существует синхронизация, чтобы обеспечить соблюдение зависимости от цикла.

Рассмотрим следующее, синхронная петля с зависимостью S1[i] ->T S1[i+1].

for (int i = 1; i < n; ++i) {
    a[i] = a[i-1] + b[i] + 1;
}

Каждая итерация цикла выполняет два действия

  • Рассчитать a[i-1] + b[i] + 1
  • Назначить значение a[i]

Расчет значения a[i-1] + b[i] + 1, а затем выполнение назначения может быть разложено на две строки (операторы S1 и S2):

S1: int tmp = b[i] + 1;
S2: a[i] = a[i-1] + tmp;

Первая строка, int tmp = b[i] + 1;, не имеет петлевых зависимости. Цикл может быть параллелизован путем расчета значения температуры параллельно, а затем синхронизировать назначение с a[i].

post(0);
for (int i = 1; i < n; ++i) {

    S1: int tmp = b[i] + 1;
    wait(i-1);

    S2: a[i] = a[i-1] + tmp;
    post(i);
}

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

Параллелизм Dopipe

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

Параллелизм Dopipe реализует трубопроводной параллелизм для зависимости от петли, где итерация петли распределяется по нескольким синхронизированным петлям. [ 1 ] Цель Dopipe - действовать как сборочная линия, где один этап запускается, как только будет достаточное количество данных на предыдущем этапе. [ 6 ]

Рассмотрим следующее, синхронный код с зависимостью S1[i] ->T S1[i+1].

for (int i = 1; i < n; ++i) {
    S1: a[i] = a[i-1] + b[i];
    S2: c[i] += a[i];
}

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

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

for (int i = 1; i < n; ++i) {
    S1: a[i] = a[i-1] + b[i];
        post(i);
}

for (int i = 1; i < n; i++) {
        wait(i);
    S2: c[i] += a[i];
}

Допустим, время исполнения S1 и S2 будет и тогда время выполнения для последовательной формы вышеупомянутого кода составляет , Теперь, поскольку существует параллелизм допипей, ускорение может быть достигнуто путем выполнения итераций в трубопроводной манере, что дает нам время исполнения , где P - количество процессора параллельно.

Смотрите также

[ редактировать ]
  1. ^ Jump up to: а беременный в дюймовый и Солихин, Ян (2016). Фуралиты параллельной архитектуры Boca Raton, FL: CRC Press. ISBN  978-1-4822-1118-4 .
  2. ^ Гофф, Джина (1991). «Практическое тестирование зависимости». Труды конференции ACM Sigplan 1991 по дизайну и реализации языка программирования - PLDI '91 . С. 15–29. doi : 10.1145/113445.113448 . ISBN  0897914287 Полем S2CID   2357293 .
  3. ^ Мерфи, Найл. «Обнаружение и эксплуатацию параллелизма в петлях Doacross» (PDF) . Кембриджский университет . Получено 10 сентября 2016 года .
  4. ^ Кави, Кришна. «Параллелизация Doall и Doacross Loops-A» . {{cite journal}}: CITE Journal требует |journal= ( помощь )
  5. ^ Unnikrishnan, Priya (2012), «Практический подход к параллелизации Doacross», Параллельная обработка Euro-Par 2012 , лекционные заметки в компьютерных науках, вып. 7484, с. 219–231, doi : 10.1007/978-3-642-32820-6_23 , ISBN  978-3-642-32819-0 , S2CID   18571258
  6. ^ «DOPIPE: эффективный подход к параллелизации моделирования» (PDF) . Intel . Получено 13 сентября 2016 года .
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 64d4e9a6a78c3f2824a40e4a5e66cf3f__1714598820
URL1:https://arc.ask3.ru/arc/aa/64/3f/64d4e9a6a78c3f2824a40e4a5e66cf3f.html
Заголовок, (Title) документа по адресу, URL1:
Loop-level parallelism - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)