OpenMP (по Бахтину) (Лекции), страница 3
Описание файла
Файл "OpenMP (по Бахтину)" внутри архива находится в папке "Лекции". PDF-файл из архива "Лекции", который расположен в категории "". Всё это находится в предмете "суперкомпьютерное моделирование и технологии" из 11 семестр (3 семестр магистратуры), которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 3 страницы из PDF
Клаузаcollapse (OpenMP 3.0)void work(int i, int j) {}void error_collapsing(int n){int i, j;#pragma omp parallel default(shared){#pragma omp for collapse (2)for (i=0; i<n; i++) {for (j=0; j < i; j++)// Ошибкаwork(i, j);}}}Клауза collapse может быть использована только для распределениявитков циклов с прямоугольным индексным пространством.28 октябряМосква, 2011Технология параллельного программирования OpenMP50 из 142Распределение витков цикла.
Клауза scheduleКлауза schedule:schedule(алгоритм планирования[, число_итераций])Где алгоритм планирования один из: schedule(static[, число_итераций]) - статическое планирование; schedule(dynamic[, число_итераций]) - динамическое планирование; schedule(guided[, число_итераций]) - управляемое планирование; schedule(runtime) - планирование в период выполнения; schedule(auto) - автоматическое планирование (OpenMP 3.0).28 октябряМосква, 2011Технология параллельного программирования OpenMP51 из 142Распределение витков цикла. Клауза schedule#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-8028 октябряМосква, 2011Технология параллельного программирования OpenMP52 из 142Распределение витков цикла.
Клауза schedule#pragma omp parallel for schedule(dynamic, 15)for(int i = 1; i <= 100; i++)Результат выполнения программы на 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.28 октябряМосква, 2011Технология параллельного программирования OpenMP53 из 142Распределение витков цикла.
Клауза scheduleчисло_выполняемых_потоком_итераций =max(число_нераспределенных_итераций/omp_get_num_threads(),число_итераций)#pragma omp parallel for schedule(guided, 10)for(int i = 1; i <= 100; i++)Пусть программа запущена на 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 итерации.28 октябряМосква, 2011Технология параллельного программирования OpenMP54 из 142Распределение витков цикла.
Клауза schedule#pragma omp parallel for schedule(runtime)for(int i = 1; i <= 100; i++) /* способ распределения витков цикла междунитями будет задан во время выполнения программы*/При помощи переменных среды:csh:setenv OMP_SCHEDULE "dynamic,4“ksh:export OMP_SCHEDULE="static,10“Windows:set OMP_SCHEDULE=autoили при помощи функции системы поддержки:void omp_set_schedule(omp_sched_t kind, int modifier);28 октябряМосква, 2011Технология параллельного программирования OpenMP55 из 142Распределение витков цикла. Клауза schedule#pragma omp parallel for schedule(auto)for(int i = 1; i <= 100; i++)Способ распределения витков цикла между нитями определяетсяреализацией компилятора.На этапе компиляции программы или во время ее выполненияопределяется оптимальный способ распределения.28 октябряМосква, 2011Технология параллельного программирования OpenMP56 из 142Распределение витков цикла.
Клауза nowaitvoid example(int n, float *a, float *b, float *z){int i;#pragma omp parallel{#pragma omp for schedule(static) nowaitfor (i=0; i<n; i++)c[i] = (a[i] + b[i]) / 2.0;#pragma omp for schedule(static) nowaitfor (i=0; i<n; i++)z[i] = sqrt(c[i]);}}Eсли количество итераций у циклов совпадает и параметры клаузыschedule совпадают (STATIC + число_итераций).28 октябряМосква, 2011Технология параллельного программирования OpenMP57 из 142Распределение витков цикла. Клауза nowaitvoid example(int n, float *a, float *b, float *z){int i;float sum = 0.0;#pragma omp parallel{#pragma omp for schedule(static) nowait reduction (+: sum)for (i=0; i<n; i++) {c[i] = (a[i] + b[i]) / 2.0;sum += c[i];}#pragma omp for schedule(static) nowaitfor (i=0; i<n; i++)z[i] = sqrt(c[i]);#pragma omp barrier… = sum}}28 октябряМосква, 2011Технология параллельного программирования OpenMP58 из 142Распределение нескольких структурных блоков междунитями (директива sections)#pragma omp sections [клауза[[,] клауза] ...]{[#pragma omp section]структурный блок[#pragma omp sectionструктурный блок ]...}где клауза одна из : private(list) firstprivate(list) lastprivate(list) reduction(operator: list) nowait28 октябряМосква, 2011void XAXIS();void YAXIS();void ZAXIS();void example(){#pragma omp parallel{#pragma omp sections{#pragma omp sectionXAXIS();#pragma omp sectionYAXIS();#pragma omp sectionZAXIS();}}}Технология параллельного программирования OpenMP59 из 142Выполнение структурного блока одной нитью (директиваsingle)#pragma omp single [клауза[[,] клауза] ...] #include <stdio.h>float x, y;структурный блок#pragma omp threadprivate(x, y)где клауза одна из :void init(float *a, float *b ) { private(list)#pragma omp single copyprivate(a,b,x,y) firstprivate(list) copyprivate(list)scanf("%f %f %f %f", a, b, &x, &y); nowait}Структурный блок будет выполнен int main () {одной из нитей.
Все остальные нити #pragma omp parallelбудут дожидаться результатов{выполнения блока, если не указанаклауза NOWAIT.float x1,y1;init (&x1,&y1);parallel_work ();}}28 октябряМосква, 2011Технология параллельного программирования OpenMP60 из 142Понятие задачи. Директива task (OpenMP 3.0)Каждая задача: Представляет собой последовательность операторов, которыенеобходимо выполнить. Включает в себя данные, которые используются при выполнении этихоператоров. Выполняется некоторой нитью.Задаются при помощи директивы:#pragma omp task [клауза[[,] клауза] ...]структурный блокгде клауза одна из : if (scalar-expression) final (scalar-expression) mergeable untied shared (list) private (list) firstprivate (list) default( shared | none )28 октябряМосква, 2011Технология параллельного программирования OpenMP61 из 142Использование директивы task#pragma omp for schedule(dynamic)for (i=0; i<n; i++) {func(i);}#pragma omp single{for (i=0; i<n; i++) {#pragma omp task firstprivate(i)func(i);}}28 октябряМосква, 2011Технология параллельного программирования OpenMP62 из 142Использование директивы tasktypedef struct node node;struct node {int data;node * next;};void increment_list_items(node * head){#pragma omp parallel{#pragma omp single{node * p = head;while (p) {#pragma omp taskprocess(p);p = p->next;}}}октября} 28Москва, 2011Технология параллельного программирования OpenMP63 из 142Содержание Современные направления развития параллельныхвычислительных систем OpenMP – модель параллелизма по управлению Конструкции распределения работы Конструкции для синхронизации нитей Система поддержки выполнения OpenMP-программ.Переменные окружения, управляющие выполнениемOpenMP-программы Наиболее часто встречаемые ошибки в OpenMPпрограммах.
Функциональная отладка OpenMP-программ Отладка эффективности OpenMP-программ28 октябряМосква, 2011Технология параллельного программирования OpenMP64 из 142Конструкции для синхронизации нитей Директива master Директива critical Директива atomic Семафоры Директива barrier Директива taskwait Директива flush Директива ordered28 октябряМосква, 2011Технология параллельного программирования OpenMP65 из 142Директива master#pragma omp masterструктурный блок/*Структурный блок будет выполнен MASTER-нитью группы. Позавершении выполнения структурного блока барьерная синхронизациянитей не выполняется*/#include <stdio.h>void init(float *a, float *b ) {#pragma omp masterscanf("%f %f", a, b);#pragma omp barrier}int main () {float x,y;#pragma omp parallel{init (&x,&y);parallel_work (x,y);}октября} 28Москва, 2011Технология параллельного программирования OpenMP66 из 142Взаимное исключение критических интерваловПри взаимодействии через общую память нити должны синхронизоватьсвое выполнение.Thread0: pi = pi + val; && Thread1: pi = pi + val;ВремяThread 01LOAD R1,pi2LOAD R2,val3ADD R1,R2Thread 1LOAD R1,pi4LOAD R2,val5ADD R1,R26STORE R1,pi7STORE R1,piРезультат зависит от порядка выполнения команд.
Требуется взаимноеисключение критических интервалов.28 октябряМосква, 2011Технология параллельного программирования OpenMP67 из 142Взаимное исключение критических интерваловРешение проблемы взаимного исключения должно удовлетворятьтребованиям:в любой момент времени только одна нить может находиться внутрикритического интервала;если ни одна нить не находится в критическом интервале, то любаянить, желающая войти в критический интервал, должна получитьразрешение без какой либо задержки;ни одна нить не должна бесконечно долго ждать разрешения на входв критический интервал (если ни одна нить не будет находиться внутрикритического интервала бесконечно).28 октябряМосква, 2011Технология параллельного программирования OpenMP68 из 142Вычисление числа .
Последовательная программаint main (){int n =100000, i;double pi, h, sum, x;h = 1.0 / (double) n;sum = 0.0;for (i = 1; i <= n; i ++){x = h * ((double)i - 0.5);sum += (4.0 / (1.0 + x*x));}pi = h * sum;printf("pi is approximately %.16f”, pi);return 0;}28 октябряМосква, 2011Технология параллельного программирования OpenMP69 из 142Вычисление числа на OpenMP с использованиемкритической секции#include <omp.h>#pragma omp critical [(name)]int main ()структурный блок{int n =100000, i;double pi, h, sum, x;h = 1.0 / (double) n;sum = 0.0;#pragma omp parallel default (none) private (i,x) shared (n,h,sum){double local_sum = 0.0;#pragma omp forfor (i = 1; i <= n; i++) {x = h * ((double)i - 0.5);local_sum += (4.0 / (1.0 + x*x));}#pragma omp criticalsum += local_sum;}pi = h * sum;printf("pi is approximately %.16f”, pi);return 0;} 28 октябряМосква, 2011Технология параллельного программирования OpenMP70 из 142Директива criticalint from_ list(float *a, int type);void work(int i, float *a);void example (){#pragma omp parallel{float *x;int ix_next;#pragma omp critical (list0)ix_next = from_ list(x,0);work(ix_next, x);#pragma omp critical (list1)ix_next = from_ list(x,1);work(ix_next, x);}}28 октябряМосква, 2011Технология параллельного программирования OpenMP71 из 142Директива atomic#pragma omp atomicexpression-stmtгде expression-stmt:x binop= exprx++++xx---xЗдесь х – скалярная переменная, expr – выражение со скалярнымитипами, в котором не присутствует переменная х.где binop - не перегруженный оператор:+*/&^|<<>>Технология параллельного программирования OpenMP72 из 142Вычисление числа на OpenMP с использованиемдирективы atomicint main (){int n =100000, i;double pi, h, sum, x;h = 1.0 / (double) n;sum = 0.0;#pragma omp parallel default (none) private (i,x) shared (n,h,sum){double local_sum = 0.0;#pragma omp forfor (i = 1; i <= n; i++) {x = h * ((double)i - 0.5);local_sum += (4.0 / (1.0 + x*x));}#pragma omp atomicsum += local_sum;}pi = h * sum;printf("pi is approximately %.16f”, pi);return 0;}28 октябряМосква, 2011Технология параллельного программирования OpenMP73 из 142СемафорыКонцепцию семафоров описал Дейкстра (Dijkstra) в 1965Семафор - неотрицательная целая переменная, которая можетизменяться и проверяться только посредством двух функций:P - функция запроса семафораP(s): [if (s == 0) <заблокировать текущий процесс>; else s = s-1;]V - функция освобождения семафораV(s): [if (s == 0) <разблокировать один из заблокированных процессов>; s= s+1;]28 октябряМосква, 2011Технология параллельного программирования OpenMP74 из 142Семафоры в OpenMPСостояния семафора:uninitializedunlockedlockedvoid omp_init_lock(omp_lock_t *lock); /* uninitialized to unlocked*/void omp_destroy_lock(omp_lock_t *lock); /* unlocked to uninitialized */void omp_set_lock(omp_lock_t *lock); /*P(lock)*/void omp_unset_lock(omp_lock_t *lock); /*V(lock)*/int omp_test_lock(omp_lock_t *lock);void omp_init_nest_lock(omp_nest_lock_t *lock);void omp_destroy_nest_lock(omp_nest_lock_t *lock);void omp_set_nest_lock(omp_nest_lock_t *lock);void omp_unset_nest_lock(omp_nest_lock_t *lock);int omp_test_nest_lock(omp_nest_lock_t *lock);28 октябряМосква, 2011Технология параллельного программирования OpenMP75 из 142Вычисление числа на OpenMP с использованиемсемафоровint main (){int n =100000, i;double pi, h, sum, x;omp_lock_t lck;h = 1.0 / (double) n;sum = 0.0;omp_init_lock(&lck);#pragma omp parallel default (none) private (i,x) shared (n,h,sum,lck){double local_sum = 0.0;#pragma omp forfor (i = 1; i <= n; i++) {x = h * ((double)i - 0.5);local_sum += (4.0 / (1.0 + x*x));}omp_set_lock(&lck);sum += local_sum;omp_unset_lock(&lck);}pi = h * sum;printf("pi is approximately %.16f”, pi);omp_destroy_lock(&lck);return 0;} 28 октябряМосква, 2011Технология параллельного программирования OpenMP76 из 142Использование семафоровint main(){omp_lock_t lck;void skip(int i) {}int id;void work(int i) {}omp_init_lock(&lck);#pragma omp parallel shared(lck) private(id){id = omp_get_thread_num();omp_set_lock(&lck);printf("My thread id is %d.\n", id); /* only one thread at a time can execute this printf */omp_unset_lock(&lck);while (! omp_test_lock(&lck)) {skip(id); /* we do not yet have the lock, so we must do something else*/}work(id); /* we now have the lock and can do the work */omp_unset_lock(&lck);}omp_destroy_lock(&lck);return 0;}28 октябряМосква, 2011Технология параллельного программирования OpenMP77 из 142Директива barrierТочка в программе, достижимая всеми нитями группы, в которой выполнение программыприостанавливается до тех пор пока все нити группы не достигнут данной точки и все задачи,выполняемые группой нитей будут завершены.#pragma omp barrierПо умолчанию барьерная синхронизация нитей выполняется:по завершению конструкции parallel;при выходе из конструкций распределения работ (for, single, sections, workshare) , еслине указана клауза nowait.#pragma omp parallel{#pragma omp master{int i, size;scanf("%d",&size);for (i=0; i<size; i++) {#pragma omp taskprocess(i);}}#pragma omp barrier}28 октябряМосква, 2011Технология параллельного программирования OpenMP78 из 142Директива barriervoid work(int i, int j) {}void wrong(int n){#pragma omp parallel default(shared){int i;#pragma omp forfor (i=0; i<n; i++) {work(i, 0);/* incorrect nesting of barrier region in a loop region */#pragma omp barrierwork(i, 1);}}}28 октябряМосква, 2011Технология параллельного программирования OpenMP79 из 142Директива barriervoid work(int i, int j) {}void wrong(int n){#pragma omp parallel default(shared){int i;#pragma omp critical{work(i, 0);/* incorrect nesting of barrier region in a critical region */#pragma omp barrierwork(i, 1);}}}28 октябряМосква, 2011Технология параллельного программирования OpenMP80 из 142Директива barriervoid work(int i, int j) {}void wrong(int n){#pragma omp parallel default(shared){int i;#pragma omp single{work(i, 0);/* incorrect nesting of barrier region in a single region */#pragma omp barrierwork(i, 1);}}}28 октябряМосква, 2011Технология параллельного программирования OpenMP81 из 142Директива taskwait#pragma omp taskwaitint main () {int res;int fibonacci(int n) {int i, j;if (n<2)return n;else {#pragma omp task shared(i)i=fibonacci (n-1);#pragma omp task shared(j)j=fibonacci (n-2);#pragma omp taskwaitreturn i+j;}}#pragma omp parallel{#pragma omp single{int n;scanf("%d",&n);#pragma omp task shared(res)res = fibonacci(n);}}printf (“Finonacci number = %d\n”, res);}28 октябряМосква, 2011Технология параллельного программирования OpenMP82 из 142Директива flush#pragma omp flush [(список переменных)]По умолчанию все переменные приводятся в консистентное состояние (#pragmaomp flush):При барьерной синхронизацииПри входе и выходе из конструкций parallel, critical и ordered.При выходе из конструкций распределения работ (for, single, sections,workshare), если не указана клауза nowait.При вызове omp_set_lock и omp_unset_lock.При вызове omp_test_lock, omp_set_nest_lock, omp_unset_nest_lockи omp_test_nest_lock, если изменилось состояние семафора.При входе и выходе из конструкции atomic выполняется #pragma omp flush(x), гдеx – переменная, изменяемая в конструкции atomic.28 октябряМосква, 2011Технология параллельного программирования OpenMP83 из 142Содержание Современные направления развития параллельныхвычислительных систем OpenMP – модель параллелизма по управлению Конструкции распределения работы Конструкции для синхронизации нитей Система поддержки выполнения OpenMP-программ.Переменные окружения, управляющие выполнениемOpenMP-программы Наиболее часто встречаемые ошибки в OpenMPпрограммах.