1 Введение в OpenMP Параллельное программирование
2 Архитектура вычислительных систем SMP
3 Содержание Введение в OpenMP Модель программирования и запуска Параллельные области Синтаксис Область видимости данных Переменные окружения Подпрограммы библиотеки OpenMP Директивы работы с общей памятью Синхронизация Критические области
4 OpenMP OpenMP стандарт параллельного программирования для систем с общей памятью Переносимость на любые архитектуры с разделяемой памятью Позволяет увеличить параллелизм программы Компилятор основан на расширении существующих языков программирования Главным образом с помощью директив Несколько библиотек подпрограмм Поддерживаются языки Фортран и С/С++ OpenMP стандартизован
5 использование OpenMP
6 OpenMP – это простой подход для мультинитевого программирования Мультинити используются на новых аппаратных платформах: Intel CPU поддерживают Hyperthreading AMD Opterons создают блоки для бюджетных SMP машин Многоядерные CPU IBM Power CPU SUN UltraSPARC IV HP PA8800
7 Где используется OpenMP?
8 Количество процессоров, на которых можно запускать OpenMP программу
9 Гибридные приложения (OpenMP+MPI)
10 Простота программирования OpenMP Большинство конструкций OpenMP пишутся в виде директив или комментариев Основной упор в OpenMP делается на распараллеливание циклов OpenMP увеличивает параллелизм программы
11 Кто разрабатывает OpenMP? ASCI Program of the US DOE Compaq Computer Corporation EPCC (Edinburgh Parallel Computing Center) Fujitsu Hewlett-Packard Company Intel Corporation International Business Machines (IBM) Silicon Graphics, Inc. Sun Microsystems, Inc. cOMPunity NEC
12 История создания OpenMP 1997 OpenMP Fortran OpenMP C/C OpenMP Fortran OpenMP Fortran OpenMP C/C OpenMP OpenMP 3.0
13 Доступность OpenMP Доступны реализации OpenMP для любых платформ и для любых компиляторов языков Фортран, С/С++ Производитель CPUФортранCC++ HP+++ IBM+++ SGI+++ SUN+++ Cray+++ Hitachi SR NEC SX+++ Intel IA32+++ Intel IA64+++ AMD X
14 Литература OpenMP Homepage: OpenMP user group OpenMP at HLRS: R.Chandra, L. Dagum, D. Kohr, D. Maydan, J. McDonald, R. Menon: Parallel programming in OpenMP. R. Eigenmann, Michael J. Voss (Eds): OpenMP Shared Memory Parallel Programming.
15 Содержание Введение в OpenMP Модель программирования и запуска Параллельные области Синтаксис Область видимости данных Переменные окружения Подпрограммы библиотеки OpenMP Директивы работы с общей памятью Синхронизация Критические области
16 Модель программирования OpenMP OpenMP – это модель программирования с общей памятью Нагрузка распределяется между нитями Переменные: Общие для всех нитей Дублированные для каждой нити Нити взаимодействуют через общие переменные Непреднамеренное разделение данных между нитями может привести к состоянию «гонки нитей»: Синхронизация используется для защиты данных от конфликта
17 Модель запуска OpenMP Последовательная часть Параллельная область Последовательная часть Параллельная область Последовательная часть Группа нитей Главная нить Team of Threads Master Thread
18 Модель запуска OpenMP Модель вызова ветвей при параллельном выполнении Программа запускается как один процесс Master thread Старт параллельных конструкций: Master thread создает группы нитей Завершение параллельных конструкций: Производится синхронизация нитей (implicit barrier) Продолжает выполнение только Master thread
19 Конструкции OpenMP: Параллельные области Фортран: С/C++: !$OMP PARALLEL block !$OMP END PARALLEL #pragma omp parallel structured block /* omp end parallel */
20 Конструкции OpenMP: Синтаксис Фортрана Блок кода программы параллельно запускается с помощью мультинитей. Запуск одного и того же кода программы для каждой нити избыточен! !$OMP PARALLEL [ clause [, ]... ] block !$OMP END PARALLEL parallel/end parallel эта пара директив должна быть описана в рамках одной процедуры
21 Конструкции OpenMP: Синтаксис Си #pragma omp parallel [ clause [ clause ]... ] new-line structured-block clause – может принимать одно из следующих значений: private(list) shared(list)...
22 OpenMP: Директивы языка Фортран Нити в Фортране описываются в виде комментариев Format: sentinel directive_name [ clause [ [, ] clause ]... ] Комментарии начинаются с первого столбца: Фиксированный формат: !$OMP | C$OMP | *$OMP Свободный формат: !$OMP OpenMP не восприимчив к способу описания Условия компиляции Фиксированный формат : !$ _ | C$ _ | *$ _ Свободный формат : !$ _ #ifdef _OPENMP [ in my_fixed_form.For block or my_free_form.F90 ] #endif Пример: !$ write(*,*) OMP_GET_NUM_PROCS(), avail. processors
23 OpenMP: Директивы языка С/С++ #pragma директивы Format: #pragma omp directive_name [ clause [ clause ]... ] new-line Условия компиляции #ifdef _OPENMP printf(%d avail.processors\n, omp_get_num_procs()); #endif OpenMP не восприимчив к способу описания Подключение файлов библиотеки подпрограмм: #ifdef _OPENMP #include #endif
24 OpenMP: Область видимости данных private ( list ) объявление переменных в list, уникальных в рамках каждой нити в группе shared ( list ) объявление переменные в list, общих для всех нитей в группе по умолчанию объявление переменных shared, кроме случаев: стек переменных при вызове процедуры PRIVATE автоматические переменные в блоке PRIVATE Индексы циклов в parallel OMP DO (Fortran) for (C) F=-1 F=0F=1F=2F=3 F=-1
25 OpenMP: переменные окружения OMP_NUM_THREADS количество нитей используемое во время запуска когда включена опция динамического корректирования количества нитей, значение этой переменной окружения определяет максимальное количество используемых нитей setenv OMP_NUM_THREADS 16 [csh, tcsh] export OMP_NUM_THREADS=16 [sh, ksh, bash] OMP_SCHEDULE применяется только для директив do/for и parallel do/for имеющих тип schedule RUNTIME устанавливает тип schedule и размер части цикла for для всех циклов setenv OMP_SCHEDULE GUIDED,4 [csh, tcsh] export OMP_SCHEDULE=GUIDED,4 [sh, ksh, bash]
26 библиотека OpenMP Вызовы функций Исполняемые функции Режим запуска Вложенный параллелизм Функции блокировки C/C++: добавить #include Fortran: добавить объявление всех необходимых процедур OMP, т.е., !$ INTEGER omp_get_thread_num
27 библиотека OpenMP Функция OMP_GET_NUM_THREADS Возвращает количество нитей, корректно работающих в группе, в параллельной области, которая выполняется в настоящий момент Fortran: integer function omp_get_num_threads() C/C++: int omp_get_num_threads(void); Функция OMP_GET_THREAD_NUM Возвращает номер нити в группе, от 0 до omp_get_num_threads()-1. Мастер нить в группе имеет номер 0. Fortran: integer function omp_get_thread_num() C/C++: int omp_get_thread_num(void);
28 библиотека OpenMP: функции замера времени DOUBLE PRECISION FUNCTION OMP_GET_WTIME() Определяет время работы START=OMP_GET_WTIME() ! Измеряемая часть программы END = OMP_GET_WTIME() PRINT *, ´Work took ´, END-START, ´ seconds´ определяет per-thread time локальное время работы нити DOUBLE PRECISION FUNCTION OMP_GET_WTICK() Возвращает количество секунд между двумя временными тактами
29 Содержание Введение в OpenMP Модель программирования и запуска Параллельные области Синтаксис Область видимости данных Переменные окружения Подпрограммы библиотеки OpenMP Директивы работы с общей памятью Синхронизация Критические области
30 OpenMP: Директивы работы с общей памятью Деление выполняемого компилированного кода программы между нитями в группе Динамическая компиляция с параллельными областями Неявная синхронизация на входе Директивы sections do директивы (Fortran) for директивы (C/C++)
31 OpenMP: Директивы sections – C/C++ A=…C=…E=…G=… B=…D=…F=…H=… С/C++: #pragma omp parallel { #pragma omp sections { {a=…; b=…;} #pragma omp section {c=…; d=…;} #pragma omp section {e=…; f=…;} #pragma omp section {g=…; h=…;} }/* omp end sections */ }/* omp end parallel */
32 OpenMP: Директивы sections – Фортран A=…C=…E=…G=… B=…D=…F=…H=… Фортран: !$OMP PARALLEL !$OMP SECTIONS a=… b=… !$OMP SECTION c=… d=… !$OMP SECTION e=… f=… !$OMP SECTION g=… h=… !$OMP END SECTIONS !$OMP END PARALLEL
33 OpenMP: Директивы sections – синтаксис Fortran: !$OMP SECTIONS [ clause [ [, ] clause ]... ] [!$OMP SECTION ] block1 [!$OMP SECTION block2 ]... !$OMP END SECTIONS [ nowait ] C/C++: #pragma omp sections [ clause [ clause ]... ] new-line { [ #pragma omp section new-line ] structured-block1 [ #pragma omp section new-line structured-block2 ]... }
34 OpenMP: Директивы sections – C/C++ i= 0,4 i= 5,9 i= 10,14 i= 15,19 a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… С/C++: #pragma omp parallel private(f) { f=7; #pragma omp for for (i=0; i
35 OpenMP: Директивы sections – Фортран i= 1,5 i= 6,10 i= 11,15 i= 16,20 a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… Фортран: !$OMP PARALLEL private(f) f=7 !$OMP DO do i=1, 20 a(i) = b(i) + f*i end do !$OMP END DO !$OMP END PARALLEL f=7
36 OpenMP: Директивы do/for – синтаксис выполняется поиск цикла, запущенного в блоке parallel Fortran: !$OMP do [ clause [ [, ] clause ]... ] do_loop [ !$OMP end do [ nowait ] ] директива end do, должна следовать непосредственно после конца цикла C/C++: #pragma omp for [ clause [ clause ]... ] new-line for-loop соответствующий цикл for должен иметь каноническую форму
37 OpenMP: Директивы do/for – детали clause может быть: private (list) reduction (operator : list) schedule ( type [, chunk ] ) nowait (C/C++: on #pragma omp for ) (Fortran: on !$OMP END DO ) В конце цикла do/for ставится неявный барьер, если не определена спецификация nowait. Если определена спецификация nowait, то нити не делают синхронизацию в конце параллельного цикла. schedule clause определяет как происходит деление итераций цикла между нитями в группе.
38 OpenMP: спецификация планировщика В schedule ( type [, chunk ] ) type определяется как: static dynamic guided runtime
39 OpenMP: спецификация планировщика static: Итерации делятся на части, размер которых определен в chunk. Части статически заданны для нитей в группе в круговой циклической форме в порядке следования номеров нитей. По умолчанию размер части: одна непрерывная часть для каждой нити. dynamic: Итерации разбиваются на части, размера chunk. Как только каждая нить заканчивает часть, она динамически получает следующую часть. По умолчанию размер части: 1.
40 OpenMP: спецификация планировщика guided: Размер части уменьшается экспоненциально на каждом итерационном шаге. chunk определяется как наименьшая из возможных частей. По умолчанию размер части: 1. runtime: Решение относительно scheduling не принимается, пока программа не загружена. Тип schedule и размер блока может быть выбран на этапе запуска через переменную окружения OMP_SCHEDULE.
41 OpenMP: планировщик (пример использования) цикл распределен с помощью SCHEDULE(x[,p]): static Циклическое разбиение на равные блоки. dynamic Каждая доступная нить получает блокразмера p (default 1) и распределение происходит динамически. guided Экспоненциальное уменьшение размеров блоков.
42 Часть вторая …
43 директива WORKSHARE Директива WORKSHARE распараллеливание встроенных циклов и циклов FORALL Использование: !$OMP WORKSHARE A=B ! Rest of block !$OMP END WORKSHARE Семантика: Работа внутри блока делиться на непересекающиеся части. Каждый встроенный элемент должен быть вычислен один раз. Элементы вычисляются разными нитями. Компилятор должен понимать семантику векторных циклов. Моделируется PARALLEL DO с неявным циклом.
44 Содержание Введение в OpenMP Модель программирования и запуска Параллельные области Синтаксис Область видимости данных Переменные окружения Подпрограммы библиотеки OpenMP Директивы работы с общей памятью Синхронизация Критические области
45 OpenMP: синхронизация Выполнение неявного барьера: В начале и в конце параллельного блока В конце всех других управляющих конструкций Неявная синхронизация в параллельной области может быть отменена оператором nowait Явная синхронизация critical...
46 OpenMP: директива critical Условия выполнения кода программы Запускается блок кода всеми нитями, но одновременно выполняется только одной нитью Fortran: !$OMP CRITICAL [ ( name ) ] block !$OMP END CRITICAL [ ( name ) ] C/C++: #pragma omp critical [ ( name ) ] new-line structured-block Нить ждет в начале критического блока пока, другая нить в группе выполняет критический блок с тем же самым названием.
47 OpenMP: critical пример (C/C++) cnt=0 f=7 i= 0,4 i= 5,9 i= 10,14 i= 15,19 a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… С/C++: cnt=0; f=7; #pragma omp parallel { #pragma omp for for (i=0; i
48 OpenMP: critical пример (Fortran) cnt=0 f=7 i= 1,5 i= 6,10 i= 11,15 i= 16,20 a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… if cnt+1 Фортран: cnt=0 f=7 !$OMP PARALLEL !$OMP DO do i=1, 20 if (b(i).eq.0) then !$OMP CRITICAL cnt=cnt+1 !$OMP END CRITICAL end if a(i) = b(i) + f*i end do !$OMP END DO !$OMP END PARALLEL
49 OpenMP: critical пример 2 (C/C++) mx=0 pmax =0 pmax =0 pmax =0 pmax =0 С/C++: mx=0; #pragma omp parallel private(pmax) { pmax=0; #pragma omp for private(r) for (i=0; ipmax ? r : pmax); } /* end for */ /* omp end for*/ #pramga omp critical mx=(pmax>mx ? pmax : mx); /* omp end critical */ }/* omp end parallel */ i= 0,4 i= 5,9 i= 10,14 i= 15,19 r=… pmax =…) pmax =…) pmax =…) pmax =…) enddo mx= max(mx,pmax) enddo
50 OpenMP: critical пример 2 (Fortran) mx=0 pmax =0 pmax =0 pmax =0 pmax =0 i= 1,5 i= 6,10 i= 11,15 i= 16,20 r=… pmax =…) pmax =…) pmax =…) pmax =…) enddo mx= max(mx,pmax) enddo Фортран: mx=0 !$OMP PARALLEL PRIVATE(pmax) pmax=0 !$OMP DO PRIVATE(r) do i=1,20 r=work(i) pmax=max(pmax,r) end do !$OMP END DO !$OMP CRITICAL mx=max(mx,pmax) !$OMP END CRITICAL !$OMP END PARALLEL
51 Терминология OpenMP Статический блок параллельной конструкции: инструкции, включенные лексически в пределах конструкции Динамический блок параллельной конструкции: включает подпрограммы, вызванные изнутри конструкции повисшие директивы : не появившиеся в лексическом блоке параллельной конструкции, но лежащие в динамическом блоке Параллельные конструкции в верхнем уровне дерева, вызываемой программы Директивы в любой из вызванных подпрограмм
52 Терминология OpenMP
53 OpenMP: Управляющие конструкции Конструкция, обозначающая параллельную область parallel Конструкции, используемые при совместной работе нитей sections do (Fortran) for (C/C++) Комбинированные конструкции, обозначающие параллельную и совместную работу parallel do (Fortran) parallel for (C/C++) Синхронизирующие конструкции critical
54 OpenMP: Область видимости данных private ( list ) Переменные, объявленные в списке, являются уникальными в каждой нити в группе shared ( list ) Переменные, которые указываются в списке, являются общедоступными для всех потоков в группе
55 OpenMP: Область видимости данных По умолчанию тип переменных - shared, кроме случаев стек переменных при вызове процедуры PRIVATE автоматические переменные в блоке PRIVATE Индексы циклов в parallel OMP DO (Fortran) for (C) Рекомендация: Избегите уникальных переменных, используйте локальные переменные в блоке (возможный только для C/C ++)
56 OpenMP: Область видимости данных (Private) Уникальная переменная создает локальную копию переменной для каждой нити значение переменной не определено Уникальная переменная не связана с той областью памяти, где хранится оригинал program wrong JLAST = -777 !$OMP PARALLEL DO PRIVATE(JLAST) DO J=1, JLAST = J END DO !$OMP END PARALLEL DO print *, JLAST > writes -777 !!!
57 OpenMP: Область видимости данных (Private) Если необходима начальная инициализация используется FIRSTPRIVATE( var ) Если необходимо получить значение после того, как цикл выполниться используется LASTPRIVATE( var ) Значение переменной модифицируется нитью, которая проводит вычисление последней итерации (on do or for loops) в последней секции
58 часть 2
59 OpenMP: предварительная обработка область reduction (operator: list) Выполняет предварительную обработку переменных, которые появляются в list, с оператором operator operator: один из Фортран: +, *, -,.and.,.or.,.eqv.,.neqv. or max, min, iand, ior, or ieor C/C++: +, *, -, &, ^, |, &&, or ||
60 OpenMP: предварительная обработка область (2) Переменные должны иметь атрибут shared В OpenMP 2.0 переменные могут быть массивами (ФОРТРАН) В конце обработки reduction, переменная модифицируется, чтобы отразить результат объединения первоначального значения переменной с конечным значением каждой из частных копий, используя указанный оператор
61 OpenMP: reduction пример (Fortran) sm=0 i= 1,5 i= 6,10 i= 11,15 i= 16,20 r=… sm= sm+r sm= sm+r sm= sm+r sm= sm+r enddo Фортран: sm=0 !$OMP PARALLEL DO PRIVATE(r), REDUCTION(+: sm) do i=1,20 r=work(i) sm=sm+r end do !$OMP END PARALLEL DO
62 OpenMP: reduction пример (C/C++) mx=0 С/C++: sm=0; #pragma omp parallel for reduction(+: sm) for (i=0; i
63 OpenMP: комбинированная директива parallel do/for Сокращенная форма определяет параллельную область, которая содержит единственную директиву do/for Фортран: !$OMP PARALLEL DO [ clause [ [, ] clause ]... ] do_loop [ !$OMP END PARALLEL DO ] C/C++: #pragma omp parallel for [ clause [ clause ]... ] new-line for-loop
64 OpenMP: комбинированная директива parallel do/for – пример (Fortran) Фортран: f=7 !$OMP PARALLEL DO do i=1,20 a(i) = b(i)+ f*i end do !$OMP END PARALLEL DO f=7 i= 1,5 i= 6,10 i= 11,15 i= 16,20 a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+… a(i)= b(i)+…
65 OpenMP: комбинированная директива parallel do/for – пример (C/C++) С/C++: f=7; #pragma omp parallel for for (i=0; i
66 Синхронизация OpenMP Параллельное программирование
67 Синхронизирующие конструкции master critical barrier taskwait atomic flush ordered
68 OpenMP: директива master Условия выполнения кода программы Запускается блока кода только мастер нитью Fortran: !$OMP MASTER [ ( name ) ] block !$OMP END MASTER [ ( name ) ] C/C++: #pragma omp master [ ( name ) ] new-line structured-block
69 OpenMP: директива master (пример) SUBROUTINE A15( X, XOLD, N, TOL ) REAL X(*), XOLD(*), TOL INTEGER N INTEGER C, I, TOOBIG REAL ERROR, Y, AVERAGE EXTERNAL AVERAGE C = 0 TOOBIG = 1 !$OMP PARALLEL DO WHILE( TOOBIG > 0 ) !$OMP DO PRIVATE(I) DO I = 2, N-1 XOLD(I) = X(I) ENDDO !$OMP SINGLE TOOBIG = 0 !$OMP END SINGLE !$OMP DO PRIVATE(I,Y,ERROR), REDUCTION(+:TOOBIG) DO I = 2, N-1 Y = X(I) X(I) = AVERAGE( XOLD(I-1), X(I), XOLD(I+1) ) ERROR = Y-X(I) IF( ERROR > TOL.OR. ERROR < -TOL ) TOOBIG = TOOBIG+1 ENDDO !$OMP MASTER C = C + 1 PRINT *, 'Iteration ', C, 'TOOBIG=', TOOBIG !$OMP END MASTER ENDDO !$OMP END PARALLEL END SUBROUTINE A15
70 OpenMP: директива critical Условия выполнения кода программы Запускается блок кода всеми нитями, но одновременно выполняется только одной нитью Fortran: !$OMP CRITICAL [ ( name ) ] block !$OMP END CRITICAL [ ( name ) ] C/C++: #pragma omp critical [ ( name ) ] new-line structured-block Нить ждет в начале критического блока пока, другая нить в группе выполняет критический блок с тем же самым названием.
71 OpenMP: директива barrier Условия выполнения кода программы Конструкция запускается всеми нитями Fortran: !$OMP BARRIER C/C++: #pragma omp barrier new-line Конструкция определяет явный барьер для всех нитей. Выполнение нитей будет продолжено после того, как все нити выполнят указанную конструкцию.
72 OpenMP: директива taskwait Условия выполнения кода программы Конструкция запускается всеми нитями Fortran: !$OMP TASKWAIT C/C++: #pragma omp taskwait new-line Конструкция taskwait ожидает завершения дочерних процессов, сгенерированных с начала текущей программы.
73 OpenMP: директива atomic Условия выполнения кода программы Конструкция запускается всеми нитями Fortran: !$OMP ATOMIC statement C/C++: #pragma omp atomic new-line expression-stmt Конструкция atomic гарантирует, что выделенная область памяти будет обновляться атомарно, вместо того, чтобы подвергнуться возможности многократных и одновременных записей нитями.
74 OpenMP: директива atomic (пример) SUBROUTINE A20_1_WRONG() INTEGER:: I REAL:: R EQUIVALENCE(I,R) !$OMP PARALLEL !$OMP ATOMIC I = I + 1 !$OMP ATOMIC R = R ! incorrect because I and R reference the same ! location but have different types !$OMP END PARALLEL Fortran END SUBROUTINE A20_1_WRONG
75 OpenMP: директива flush Условия выполнения кода программы Конструкция запускается всеми нитями Fortran: !$OMP FLUSH [(list)] C/C++: #pragma omp flush [(list)] new-line Конструкция flush отключает выполнение OpenMP операторов. Эта операция делает совместимыми с общей памятью нитевые временные переменные, и предписывает порядок выполнения операций доступа к памяти, явно определенных переменных.
76 OpenMP: директива ordered Условия выполнения кода программы Запускается блока кода только мастер нитью Fortran: !$OMP ORDERED [ ( name ) ] block !$OMP END ORDERED [ ( name ) ] C/C++: #pragma omp ordered [ ( name ) ] new-line structured-block Конструкция ordered определяет структурированный блок в области цикла, которая выполнится в порядке итераций цикла. Последовательный и упорядоченный код в пределах области, код вне области выполниться параллельно.
77 Операторы управления OpenMP Параллельное программирование
78 Операторы управления параллельными конструкциями Конструкциями распределения заданий Директивы OpenMP поддерживают множество операторов (clause), которые обеспечивают простой способ управления поведением конструкции.
79 Операторы управления Shared Clause Private Clause Lastprivate Clause Firstprivate Clause Default Clause Nowait Clause
80 Оператор shared Оператор shared используется, чтобы определить, какие данные будут общими для всех нитей, выполняющих параллельную область. Все нити могут свободно читать или изменять значение общих переменных. Синтаксис: shared (list) Пример: #pragma omp parallel for shared(a) for (i=0; i
81 Оператор shared Важное свойство атрибута shared: несколько нитей могут попытаться одновременно обновить одну и ту же область памяти; одна нить может пробовать читать область, которую обновляет другая нить. Программист должен гарантировать, что ни одна из этих ситуаций не произойдет и что доступ к общим данным будет упорядочен так как требуется алгоритмом. Операторы синхронизации OpenMP позволяют избежать соревнования нитей.
82 Оператор private Так как итерации цикла распределены по нитям группы, каждой нити нужно дать уникальную и локальную копию переменной цикла i так, чтобы безопасно изменить значение. Иначе, изменение i одной нитью затронуло бы значение i в памяти другой нити, таким образом лишающая возможности нить сохранять ее собственный набор итераций. В операторе private могут быть указаны любые переменные параллельной области, для которых нитям нужно дать их собственные копии. Синтаксис: private (list) Пример: #pragma omp parallel for private(i,a) for (i=0; i
83 Оператор lastprivate Оператор lastprivate используется, если необходимо значение после выполнения итераций цикла. Синтаксис: lastprivate (list) Это гарантирует, что будет доступно последнее значение переменной, после выполнения параллельной области. для циклов – значение последней итерации; для других областей – значение последнего выражения.
84 Оператор lastprivate Пример: #pragma omp parallel for private(i) lastprivate(a) for (i=0; i
85 Оператор lastprivate Пример 2: #pragma omp parallel for private(i) private(a) shared(a_shared) for (i=0; i
86 Оператор firstprivate Оператором firstprivate выполняется начальная инициализация частных переменных для всех нитей. Оператор firstprivate может быть использован: в параллельной конструкции; в циклах; в параллельных секциях (sections); в последовательных конструкциях (single). Синтаксис: firstprivate (list)
87 Оператор firstprivate Пример: for(i=0; i
88 Оператор firstprivate Результат: a[0] = -1 a[1] = -2 a[2] = -3 a[3] = -4 a[4] = 1 a[5] = 1 a[6] = 2 a[7] = 2 a[8] = 3 a[9] = 3
89 Оператор firstprivate Пример 2: #pragma omp parallel default(none) \ private(i,TID,indx) shared(n,offset,a) { TID = omp_get_thread_num(); indx = offset + n*TID; for(i=indx; i
90 Оператор default Оператор default используется, чтобы задать переменным признак совместного использования переменных по умолчанию. Например: Оператор default назначает атрибут общедоступный на все переменные, на которые ссылаются в конструкции. Оператор default(private), который не поддерживается в C/C ++, делает все переменные частными по умолчанию. Это применимо к параллельной конструкции только. Синтаксис: default (none | shared) default (none | shared | private) Этот оператор чаще всего используется, чтобы определить атрибут для совместно используемых переменных в параллельной области. Только исключения должны быть явно перечислены: #pragma omp for default(shared) private(a,b,c)
91 Применение OpenMP Уравнение теплопроводности
92 Применение OpenMP: Уравнение теплопроводности решает уравнение теплопроводности df/dt=Df использует явную схему: конечные разности вперед для аппроксимации по времени центральные разности для аппроксимации по пространству решает уравнение в квадратной области Начальные условия: f=0 внутри области Граничные условия: f=x на всей границе Количество узлов сетки по каждому направлению: 80
93 Применение OpenMP: Уравнение теплопроводности Цели тестирования: Оценить параллелизм реального приложения Оценить эффективность различных методов распараллеливания Последовательная программа: Fortran77: heat.f and scdiff.f90 Fortran90: heat.f90 and scdiff.f90 C: heat.c
94 Применение OpenMP: Уравнение теплопроводности 3 версии программы: маленькая сетка: heat Размер сетки 20 x 11, количество итераций Вывод начальных и конечных значений массивов средняя сетка: heat-big Размер сетки 80 x 80, количество итераций Значений массивов не выводились большая сетка: heat-opt Размер сетки 150 x 150, количество итераций Значений массивов не выводились
95 Применение OpenMP: Уравнение теплопроводности распараллеливание с использованием различных методов и результатов проверки критическая директива critical директива предварительной обработки ( reduction ) директива параллельной области + директива, используемая при совместной работе нитей комбинированная директива, обозначающая параллельную и совместную работу замеряется время выполнения программы
96 Применение OpenMP: Уравнение теплопроводности используется clause SCHEDULE с различными значениями для type и chunk и замеряется время выполнения дополнительно: распараллеливается версия для использования с опцией компилятора -O3
97 Применение OpenMP: Уравнение теплопроводности heat.[f|f90|c]: первоначальная программа heatc.[f|f90|c]: решение с директивой critical, одна параллельная область вне цикла по времени heatc2.[f|f90|c]: решение с директивой critical вне внутреннего цикла, одна параллельная область вне цикла по времени heatr.[f|f90|c]: решение с директивой reduction clause, одна параллельная область вне цикла по времени heatp.[f|f90|c]: решение с директивой reduction clause, комбинация из двух параллельных областей heats.[f|f90|c]: то же, что и heatr.[f|f90|c], с добавлением директивы schedule (runtime) clause heat?-big.[f|f90|c] и heat?-opt.[f|f90|c]: соответствующие версии с размером сетки 80x80 и 150x150, с опцией -O3 компилятора
98 Применение OpenMP: Уравнение теплопроводности - время выполнения F90/opt