Professional Documents
Culture Documents
Lab 02
Lab 02
Теоретичнi вiдомостi
1
• reduction(оператор: список) – задає оператор i список спiльних змiнних; для кожної
змiнної створюються локальнi копiї в кожному потоцi; локальнi копiї iнiцiалiзуются
вiдповiдно до типу оператора (для адитивних операцiй – 0 або його аналоги, для
мультиплiкативних операцiй – 1 або її аналоги); над локальними копiями змiнних
пiсля виконання всiх операторiв паралельної областi виконується заданий оператор;
оператори для мови Сi – +, −,∗,&,|,^,&&,||, max,min; порядок виконання операторiв
не визначений, тому результат може вiдрiзнятися вiд запуску до запуску;
• schedule(type [, chunk]) – опцiя задає, яким чином iтерацiї циклу розподiляються мiж
потоками;
• collapse(n) – вказує на те, що n щiльно вкладених послiдовних циклiв асоцiюється з
даною директивою; для циклiв утворюється загальний простiр iтерацiй, який дiлиться
мiж потоками; якщо опцiя collapse не задана, то директива стосується тiльки одного
циклу, розташованого за директивою for;
• ordered – опцiя, що говорить про те, що в циклi можуть зустрiчатися директиви
ordered; в цьому випадку визначається блок всерединi тiла циклу, який повинен вико-
нуватися в тому порядку, в якому iтерацiї йдуть в послiдовному циклi;
• nowait – пiсля виконання видiленої дiлянки вiдбувається неявна бар’єрна синхронiза-
цiя паралельно працюючих потокiв: їх подальше виконання вiдбувається тiльки тодi,
коли всi вони досягнуть даної точки; якщо в подiбнiй затримцi немає необхiдностi,
опцiя nowait дозволяє потокам, котрi вже дiйшли до кiнця дiлянки, продовжити ви-
конання без синхронiзацiї з iншими.
Якщо в блоцi директиви parallel немає нiчого, крiм директиви for, то обидвi директиви
можна об’єднати в одну, як у прикладi 2.1.
При рiзному обсязi обчислень в рiзних iтерацiях циклу бажано мати можливiсть керу-
вати розподiлом iтерацiй циклу мiж потоками – в OpenMP це забезпечується за допомогою
параметра schedule директиви for. Поле type опцiї schedule може приймати наступнi зна-
чення:
• static – статичний спосiб розподiлу iтерацiй до початку виконання циклу. Якщо по-
ле chunk не вказано, то iтерацiї дiляться порiвну мiж потоками. При заданому зна-
2
ченнi chunk iтерацiї циклу дiляться на блоки розмiру chunk i цi блоки розподiляються
мiж потоками до початку виконання циклу.
• dynamic – динамiчний спосiб розподiлу iтерацiй. До початку виконання циклу по-
токам видiляються блоки iтерацiй розмiру chunk (якщо поле chunk не вказано, то
вважається chunk = 1). Подальше видiлення iтерацiй (також блоками розмiру chunk)
здiйснюється в момент завершення потоками своїх ранiше призначених iтерацiй.
• guided – динамiчний розподiл iтерацiй, при якому розмiр блоку зменшується з деякого
початкового значення до величини chunk (за замовчуванням chunk = 1) пропорцiйно
кiлькостi ще не розподiлених iтерацiй, подiленому на кiлькiсть потокiв, що викону-
ють цикл. Розмiр початкового блоку залежить вiд реалiзацiї. У рядi випадкiв такий
розподiл дозволяє акуратнiше роздiлити роботу i збалансувати завантаження потокiв.
Кiлькiсть iтерацiй в останньому блоцi може виявитися менше значення chunk.
• auto – спосiб розподiлу iтерацiй вибирається компiлятором i/або системою виконання.
Параметр chunk при цьому не задається.
• runtime – спосiб розподiлу iтерацiй вибирається пiд час роботи програми за значен-
ням змiнної середовища OMP_SCHEDULE. Параметр chunk при цьому не задається.
Так, наприклад, для завдання динамiчного способу при розмiрi блоку iтерацiй 3, слiд
визначити:
setenv OMP_SCHEDULE "dynamic,3".
Змiнити значення змiнної OMP_SCHEDULE з програми можна за допомогою викли-
ку функцiї omp_set_schedule().
Приклад 2.2 демонструє використання опцiї schedule з рiзними параметрами. В пара-
лельнiй областi виконується цикл, iтерацiї якого будуть розподiленi мiж iснуючими потока-
ми. На кожнiй iтерацiї буде надруковано, який потiк виконав дану iтерацiю. В тiло циклу
вставлена затримка, що iмiтує деякi обчислення.
3
для ряду дiй в циклi необхiдно зберегти первинний порядок обчислень, який вiдповiдає
послiдовному виконанню iтерацiй в послiдовнiй програмi, то бажаного результату можна
досягти за допомогою директиви ordered (при цьому для директиви for повинен бути вка-
заний параметр ordered). Пояснимо сказане на фрагментi програми друку сум елементiв
рядкiв матрицi. Розрахунок вiдбуватиметься в деякому довiльному порядку, при необхiдно-
стi друку по порядку розташування рядкiв слiд додати директиву #pragma omp ordered.
#pragma omp p a r a l l e l f o r shared ( a ) p r i v a t e ( i , j , sum ) \
sched u l e ( dynamic , chunk ) ordered
{
f o r ( i =0; i < NMAX; i ++) {
sum = 0 ;
f o r ( j=i ; j < NMAX; j ++)
sum += a [ i ] [ j ] ;
#pragma omp ordered
p r i n t f ( "Сума␣ е л е м е н т i в ␣ рядка ␣%d␣ р i в н а ␣%f \n" , i , sum ) ;
}
}
Пояснимо додатково, що параметр ordered керує порядком виконання тiльки тих дiй,
якi видiленi директивою ordered – виконання решти дiй, що залишилися в iтерацiях циклу
надалi може вiдбуватися паралельно. Важливо пам’ятати також, що директива ordered
може бути застосована в тiлi циклу тiльки один раз.
Слiд зазначити, що необхiднiсть збереження порядку обчислень може призвести до за-
тримок при паралельному виконаннi iтерацiй, що обмежить можливiсть отримання макси-
мального прискорення обчислень.
4
Хiд роботи
Iндивiдуальнi завдання