Було запропоновано цю статтю або розділ з OpenMP, але, можливо, це варто додатково . Пропозиція з червня 2017. |
Синхронізація в OpenMP
Як в будь-якому іншому середовищі багато поточного програмування, в OpenMP важливу роль відіграє синхронізація. Синхронізація необхідна, якщо різні потоки працюють із спільними даними. Якщо зчитування та запис чи повторний запис спільної змінної виконуються без синхронізації, то результуюче значення змінної вважається невизначеним.
Самим простим способом захистити дані від можливих проблем, пов'язаних з одночасним доступом, є директива atomic. Ця директива застосовується до оператору-виразу одного з наступних типів: x op = expr;
x ++;
++ x;
x ––;
–– x;
де x — змінна, expr — вираз, що не посилається на x, op — бінарна операція. Дана директива забезпечує атомарність відповідної операції: в момент виконання цієї операції одним із потоків інші потоки не мають доступу до змінної х. Іншим базовим механізмом синхронізації є механізм критичних секцій. Критична секція в коді програми виділяється за допомогою директиви critical, яка має наступний синтаксис:
#pragma omp critical [name]
Опція name є необов'язковою; якщо вона відсутня, то вважається, що директива має зарезервоване не специфіковане ім'я. Таким чином, кожній критичній секції ставиться у відповідність деяке ім'я. синхронізація забезпечується наступним чином: критичні секції з однаковими іменами не можуть виконуватись одночасно.
В деяких випадках потрібно обмежити набір потоків, що виконують деякий фрагмент коду. Це досягається за допомогою директиви master, що має наступний синтаксис:
#pragma omp master
Оператор, до якого застосовується дана директива, виконується тільки головним потоком.
Розпаралелювання циклів
Більша частина часу роботи застосунків приходиться на циклічні ділянки. Тому прискоренню роботи таких ділянок за допомогою розпаралелювання приділяється велика увага. — private(list)
— firstprivate(list)
— lastprivate(list)
— reduction(operator: list)
— schedule(kind[, chunk_size])
— collapse(n)
— ordered
— nowait
Значна частина робіт по автоматичному розпаралелюванню програм присвячена саме циклам. Розпаралелюванню доцільно піддавати тільки цикли, виконання яких вносить суттєвий вклад в роботу програми. Автоматичне розгалуження таких циклів є важкою задачею для виконання. Для подолання цієї проблеми в OpenMP прийнятий загальний підхід: розробник паралельного застосунку самостійно обирає циклічні ділянки, які необхідно розпаралелити. За необхідності наявні цикли модифікуються з метою усунення інформаційних залежностей. Обрані цикли позначаються спеціальною директивою, в якій вказуються деякі параметри розподілу роботи. В процесі трансляції компілятор OpenMP генерує код, який розподіляє ітерації циклу по потокам. При цьому передбачається, що розробник впевнився у відсутності інформаційних залежностей між ітераціями. Для позначення циклів, що розпаралелюються, застосовується директива for. В програмі ця директива передує розпаралелюваному циклу типу for. При цьому цикл повинен задовольняти додаткові умови, виконання яких потрібне для того, що компілятор зміг ефективно виконати аналіз та сформувати якісний паралельний код:
#pragma omp for [клауза[[,] клауза] ...]
for (init-expr; test-expr; incr-expr) структурний блок {…} де опція (клауза) одна з:
При цьому: init-expr — або var = lb (ліва межа), або integer-type var = lb;
test-expr — var rel b, де var — змінна знакового цілого типу, rel — одна з наступних операцій порівняння: ‘<’, ‘<=’, ‘>’, ‘>=’. incr-expr — один з наступних виразів:
++var var++ –– var var–– var += incr var –=incr var = var + incr var = incr + varvar = var — incr
Слід зазначити, що змінна ітератор циклу автоматично становиться індивідуальною для всіх потоків. Стандарт OpenMP не допускає зміну її значення в тілі циклу.
Директива for повинна виконуватись всередині паралельної ділянки. Передбачена також директива parallel for, яка надає можливість поєднання функціональностя директив parallel та for в одній директиві. В результаті виконання цієї директиви створюється паралельна ділянка виконання та ітерації циклу розподіляються між потоками, що виконуються в цій ділянці.
Як приклад застосування директиви for розглянемо частину програми обчислення поелементної суми двох векторів. Спочатку розглянемо послідовну функцію обчислення суми двох векторів:
void vsum(int n, double* a, doubl* b, doubl* c){ int i; for (i = 0; i < n; i++) c[i] = a[i] + b[i]; }
Функція приймає наступні параметри: n — розмірність вектора; a, b — вектори, що додаються; c — результат.
Ітерації циклу не мають інформаційних залежностей, так як на кожній наступній ітерації обробляються нові елементи масивів a, b, c. Тому до нього можна застосувати директиву for:
void vsum(int n, double* a, doubl* b, doubl* c){ int i; #pragma omp for for (i = 0; i < n; i++) c[i] = a[i] + b[i]; }
Стратегія розподілу ітерацій циклу по потокам
Ітерації циклу, до якого застосована директива for, можуть по-різному розподілятись по потокам. Для розподілу ітерацій циклу по потокам можна використовувати клаузу schedule директиви for. Дана опція передбачає два аргументи. Перший визначає спосіб розподілу ітерацій. Другий необов'язковий аргумент задає число ітерацій в порції, яка слугує одиницею розподілу навантаження. Синтаксис цієї клаузи — schedule(алгоритм планування[,число_ітерацій]), де алгоритм планування один з:
— schedule(static[, число_ітерацій]) — статичне планування;
— schedule(dynamic[, число_ітерацій]) — динамічне планування;
— schedule(guided[, число_ітерацій]) — кероване планування;
— schedule(runtime) — планування в період виконання. Спосіб розподілу витків циклу між нитями буде задано під час виконання програми;
— schedule(auto) — автоматичне планування (OpenMP 3.0). Спосіб розподілу витків циклу між нитями визначається реалізацією компілятору. На етапі компіляції програми або під час її виконання визначається оптимальний спосіб розподілу. schedule(static[, число_ітерацій]):
#pragma omp parallel for schedule(static, 10) for(int i = 1; i <= 100; i++)
Результат виконання програми на 4-х ядерному процесорі буде наступним: — Потік 0 отримує право на виконання ітерацій 1-10, 41-50, 81-90.
— Потік 1 отримує право на виконання ітерацій 11-20, 51-60, 91-100.
— Потік 2 отримує право на виконання ітерацій 21-30, 61-70.
— Потік 3 отримує право на виконання ітерацій 31-40, 71-80.
schedule(dynamic[, число_ітерацій]):
#pragma omp parallel for schedule(dynamic, 15)
Результат виконання програми на 4-х ядерному процесорі може бути наступним:
— Потік 0 отримує право на виконання ітерацій 1-15.
— Потік 1 отримує право на виконання ітерацій 16-30.
— Потік 2 отримує право на виконання ітерацій 31-45.
— Потік 3 отримує право на виконання ітерацій 46-60.
— Потік 3 завершує виконання ітерацій.
— Потік 3 отримує право на виконання ітерацій 61-75.
— Потік 2 завершує виконання ітерацій.
— Потік 2 отримує право на виконання ітерацій 76-90.
— Потік 0 завершує виконання ітерацій.
— Потік 0 отримує право на виконання ітерацій 91-100.
schedule(guided[, число_ітерацій]):
#pragma omp parallel for schedule(guided, 10) for(int i = 1; i <= 100; i++)
число_виконуваних_потоком_ітерацій = max(число_нерозподілених_ітерацій/omp_get_num_threads(), число_ітерацій).
Нехай програма запущена на 4-х ядерному процесорі:
— Потік 0 отримує право на виконання ітерацій 1-25.
— Потік 1 отримує право на виконання ітерацій 26-44.
— Потік 2 отримує право на виконання ітерацій 45-59.
— Потік 3 отримує право на виконання ітерацій 60-69.
— Потік 3 завершує виконання ітерацій.
— Потік 3 отримує право на виконання ітерацій 70-79.
— Потік 2 завершує виконання ітерацій.
— Потік 2 отримує право на виконання ітерацій 80-89.
— Потік 3 завершує виконання ітерацій.
— Потік 3 отримує право на виконання ітерацій 90-99.
— Потік 1 завершує виконання ітерацій.
— Потік 1 отримує право на виконання 100-ї ітерації.
Примітки
- Корнеев В. В. Параллельные вычислительные системы. М.: Нолидж, 1999
- Воеводин В. В. Математические основы параллельных вычислений.- М.: Изд-во МГУ, 1991.
- С. Немнюгин, О.Стесик Параллельное программирование для многопроцессорных обчислювальних систем. — СПб: БХВ-Петербург, 2002.
Література
- Корнеев В. В. Параллельные вычислительные системы[1]. М.: Нолидж, 1999
- Воеводин В. В. Математические основы параллельных вычислений[2].- М.: Изд-во МГУ, 1991.
- С. Немнюгин, О.Стесик Параллельное программирование для многопроцессорных обчислювальних систем[3]. — СПб: БХВ-Петербург, 2002.
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Bulo zaproponovano ob yednati cyu stattyu abo rozdil z OpenMP ale mozhlivo ce varto dodatkovo Propoziciya z chervnya 2017 Sinhronizaciya v OpenMPYak v bud yakomu inshomu seredovishi bagato potochnogo programuvannya v OpenMP vazhlivu rol vidigraye sinhronizaciya Sinhronizaciya neobhidna yaksho rizni potoki pracyuyut iz spilnimi danimi Yaksho zchituvannya ta zapis chi povtornij zapis spilnoyi zminnoyi vikonuyutsya bez sinhronizaciyi to rezultuyuche znachennya zminnoyi vvazhayetsya neviznachenim Samim prostim sposobom zahistiti dani vid mozhlivih problem pov yazanih z odnochasnim dostupom ye direktiva atomic Cya direktiva zastosovuyetsya do operatoru virazu odnogo z nastupnih tipiv x op expr x x x x de x zminna expr viraz sho ne posilayetsya na x op binarna operaciya Dana direktiva zabezpechuye atomarnist vidpovidnoyi operaciyi v moment vikonannya ciyeyi operaciyi odnim iz potokiv inshi potoki ne mayut dostupu do zminnoyi h Inshim bazovim mehanizmom sinhronizaciyi ye mehanizm kritichnih sekcij Kritichna sekciya v kodi programi vidilyayetsya za dopomogoyu direktivi critical yaka maye nastupnij sintaksis pragma omp critical name Opciya name ye neobov yazkovoyu yaksho vona vidsutnya to vvazhayetsya sho direktiva maye zarezervovane ne specifikovane im ya Takim chinom kozhnij kritichnij sekciyi stavitsya u vidpovidnist deyake im ya sinhronizaciya zabezpechuyetsya nastupnim chinom kritichni sekciyi z odnakovimi imenami ne mozhut vikonuvatis odnochasno V deyakih vipadkah potribno obmezhiti nabir potokiv sho vikonuyut deyakij fragment kodu Ce dosyagayetsya za dopomogoyu direktivi master sho maye nastupnij sintaksis pragma omp master Operator do yakogo zastosovuyetsya dana direktiva vikonuyetsya tilki golovnim potokom Rozparalelyuvannya ciklivBilsha chastina chasu roboti zastosunkiv prihoditsya na ciklichni dilyanki Tomu priskorennyu roboti takih dilyanok za dopomogoyu rozparalelyuvannya pridilyayetsya velika uvaga private list firstprivate list lastprivate list reduction operator list schedule kind chunk size collapse n ordered nowait Znachna chastina robit po avtomatichnomu rozparalelyuvannyu program prisvyachena same ciklam Rozparalelyuvannyu docilno piddavati tilki cikli vikonannya yakih vnosit suttyevij vklad v robotu programi Avtomatichne rozgaluzhennya takih cikliv ye vazhkoyu zadacheyu dlya vikonannya Dlya podolannya ciyeyi problemi v OpenMP prijnyatij zagalnij pidhid rozrobnik paralelnogo zastosunku samostijno obiraye ciklichni dilyanki yaki neobhidno rozparaleliti Za neobhidnosti nayavni cikli modifikuyutsya z metoyu usunennya informacijnih zalezhnostej Obrani cikli poznachayutsya specialnoyu direktivoyu v yakij vkazuyutsya deyaki parametri rozpodilu roboti V procesi translyaciyi kompilyator OpenMP generuye kod yakij rozpodilyaye iteraciyi ciklu po potokam Pri comu peredbachayetsya sho rozrobnik vpevnivsya u vidsutnosti informacijnih zalezhnostej mizh iteraciyami Dlya poznachennya cikliv sho rozparalelyuyutsya zastosovuyetsya direktiva for V programi cya direktiva pereduye rozparalelyuvanomu ciklu tipu for Pri comu cikl povinen zadovolnyati dodatkovi umovi vikonannya yakih potribne dlya togo sho kompilyator zmig efektivno vikonati analiz ta sformuvati yakisnij paralelnij kod pragma omp for klauza klauza for init expr test expr incr expr strukturnij blok de opciya klauza odna z Pri comu init expr abo var lb liva mezha abo integer type var lb test expr var rel b de var zminna znakovogo cilogo tipu rel odna z nastupnih operacij porivnyannya lt lt gt gt incr expr odin z nastupnih viraziv var var var var var incr var incr var var incr var incr varvar var incr Slid zaznachiti sho zminna iterator ciklu avtomatichno stanovitsya individualnoyu dlya vsih potokiv Standart OpenMP ne dopuskaye zminu yiyi znachennya v tili ciklu Direktiva for povinna vikonuvatis vseredini paralelnoyi dilyanki Peredbachena takozh direktiva parallel for yaka nadaye mozhlivist poyednannya funkcionalnostya direktiv parallel ta for v odnij direktivi V rezultati vikonannya ciyeyi direktivi stvoryuyetsya paralelna dilyanka vikonannya ta iteraciyi ciklu rozpodilyayutsya mizh potokami sho vikonuyutsya v cij dilyanci Yak priklad zastosuvannya direktivi for rozglyanemo chastinu programi obchislennya poelementnoyi sumi dvoh vektoriv Spochatku rozglyanemo poslidovnu funkciyu obchislennya sumi dvoh vektoriv void vsum int n double a doubl b doubl c int i for i 0 i lt n i c i a i b i Funkciya prijmaye nastupni parametri n rozmirnist vektora a b vektori sho dodayutsya c rezultat Iteraciyi ciklu ne mayut informacijnih zalezhnostej tak yak na kozhnij nastupnij iteraciyi obroblyayutsya novi elementi masiviv a b c Tomu do nogo mozhna zastosuvati direktivu for void vsum int n double a doubl b doubl c int i pragma omp for for i 0 i lt n i c i a i b i Strategiya rozpodilu iteracij ciklu po potokamIteraciyi ciklu do yakogo zastosovana direktiva for mozhut po riznomu rozpodilyatis po potokam Dlya rozpodilu iteracij ciklu po potokam mozhna vikoristovuvati klauzu schedule direktivi for Dana opciya peredbachaye dva argumenti Pershij viznachaye sposib rozpodilu iteracij Drugij neobov yazkovij argument zadaye chislo iteracij v porciyi yaka sluguye odiniceyu rozpodilu navantazhennya Sintaksis ciyeyi klauzi schedule algoritm planuvannya chislo iteracij de algoritm planuvannya odin z schedule static chislo iteracij statichne planuvannya schedule dynamic chislo iteracij dinamichne planuvannya schedule guided chislo iteracij kerovane planuvannya schedule runtime planuvannya v period vikonannya Sposib rozpodilu vitkiv ciklu mizh nityami bude zadano pid chas vikonannya programi schedule auto avtomatichne planuvannya OpenMP 3 0 Sposib rozpodilu vitkiv ciklu mizh nityami viznachayetsya realizaciyeyu kompilyatoru Na etapi kompilyaciyi programi abo pid chas yiyi vikonannya viznachayetsya optimalnij sposib rozpodilu schedule static chislo iteracij pragma omp parallel for schedule static 10 for int i 1 i lt 100 i Rezultat vikonannya programi na 4 h yadernomu procesori bude nastupnim Potik 0 otrimuye pravo na vikonannya iteracij 1 10 41 50 81 90 Potik 1 otrimuye pravo na vikonannya iteracij 11 20 51 60 91 100 Potik 2 otrimuye pravo na vikonannya iteracij 21 30 61 70 Potik 3 otrimuye pravo na vikonannya iteracij 31 40 71 80 schedule dynamic chislo iteracij pragma omp parallel for schedule dynamic 15 Rezultat vikonannya programi na 4 h yadernomu procesori mozhe buti nastupnim Potik 0 otrimuye pravo na vikonannya iteracij 1 15 Potik 1 otrimuye pravo na vikonannya iteracij 16 30 Potik 2 otrimuye pravo na vikonannya iteracij 31 45 Potik 3 otrimuye pravo na vikonannya iteracij 46 60 Potik 3 zavershuye vikonannya iteracij Potik 3 otrimuye pravo na vikonannya iteracij 61 75 Potik 2 zavershuye vikonannya iteracij Potik 2 otrimuye pravo na vikonannya iteracij 76 90 Potik 0 zavershuye vikonannya iteracij Potik 0 otrimuye pravo na vikonannya iteracij 91 100 schedule guided chislo iteracij pragma omp parallel for schedule guided 10 for int i 1 i lt 100 i chislo vikonuvanih potokom iteracij max chislo nerozpodilenih iteracij omp get num threads chislo iteracij Nehaj programa zapushena na 4 h yadernomu procesori Potik 0 otrimuye pravo na vikonannya iteracij 1 25 Potik 1 otrimuye pravo na vikonannya iteracij 26 44 Potik 2 otrimuye pravo na vikonannya iteracij 45 59 Potik 3 otrimuye pravo na vikonannya iteracij 60 69 Potik 3 zavershuye vikonannya iteracij Potik 3 otrimuye pravo na vikonannya iteracij 70 79 Potik 2 zavershuye vikonannya iteracij Potik 2 otrimuye pravo na vikonannya iteracij 80 89 Potik 3 zavershuye vikonannya iteracij Potik 3 otrimuye pravo na vikonannya iteracij 90 99 Potik 1 zavershuye vikonannya iteracij Potik 1 otrimuye pravo na vikonannya 100 yi iteraciyi PrimitkiKorneev V V Parallelnye vychislitelnye sistemy M Nolidzh 1999 Voevodin V V Matematicheskie osnovy parallelnyh vychislenij M Izd vo MGU 1991 S Nemnyugin O Stesik Parallelnoe programmirovanie dlya mnogoprocessornyh obchislyuvalnih sistem SPb BHV Peterburg 2002 LiteraturaKorneev V V Parallelnye vychislitelnye sistemy 1 M Nolidzh 1999 Voevodin V V Matematicheskie osnovy parallelnyh vychislenij 2 M Izd vo MGU 1991 S Nemnyugin O Stesik Parallelnoe programmirovanie dlya mnogoprocessornyh obchislyuvalnih sistem 3 SPb BHV Peterburg 2002