Upload
yandex
View
4.817
Download
2
Embed Size (px)
DESCRIPTION
О.В.Сухорослов "Параллельное программирование", 16.03.2012, место показа МФТИ, Школа анализа данных (ШАД)
Citation preview
04 Параллельное программирование
О.В. Сухорослов
16.03.2011
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 1 / 66
План лекции
Системы параллельного программирования
Типовые модели программирования и шаблоны
Знакомство с технологией OpenMP
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 2 / 66
Системы параллельного программирования
Много возможных моделей программирования, отражающихразличные архитектуры параллельных систем
Модели программирования, заточенные под конкретнуюпараллельную систему
Время жизни программ обычно больше времени жизни систем
Высокоуровневые абстракции, переносимость
Середина 90-х: зоопарк систем
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 3 / 66
Текущие стандарты де-факто
Общая памятьOpenMP
Распределенная памятьMPI (Message Passing Interface)
Гибридные архитектурыOpenMP + MPIТолько MPI или OpenMP
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 4 / 66
Другие технологии
POSIX threadsC++11
CilkIntel Threading Building BlocksJava Fork-Join FrameworkGrand Central Dispatch.NET Task Parallel LibraryParallel Patterns Library
PVMGlobal ArraysUnified Parallel CX10
MapReduceDryad
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 5 / 66
Другие технологии
POSIX threadsC++11
CilkIntel Threading Building BlocksJava Fork-Join FrameworkGrand Central Dispatch.NET Task Parallel LibraryParallel Patterns Library
PVMGlobal ArraysUnified Parallel CX10
MapReduceDryad
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 5 / 66
Другие технологии
POSIX threadsC++11
CilkIntel Threading Building BlocksJava Fork-Join FrameworkGrand Central Dispatch.NET Task Parallel LibraryParallel Patterns Library
PVMGlobal ArraysUnified Parallel CX10
MapReduceDryad
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 5 / 66
Другие технологии
POSIX threadsC++11
CilkIntel Threading Building BlocksJava Fork-Join FrameworkGrand Central Dispatch.NET Task Parallel LibraryParallel Patterns Library
PVMGlobal ArraysUnified Parallel CX10
MapReduceDryadО.В. Сухорослов ()04 Параллельное программирование 16.03.2011 5 / 66
Подходы
Расширение “последовательного” языкаOpenMPCilkUPC
Библиотека к “последовательному” языкуPthreadsMPITBB
Язык со встроенной поддержкой многопроцессностиJava, C#, Erlang, Go, X10, C++12
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 6 / 66
Критерии оценки программы
Ясность
Масштабируемость
Эффективность
Удобство сопровождения
Согласованность с целевой системой
Переносимость
Эквивалентность последовательной программе
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 7 / 66
Типовые модели программирования и шаблоны
SPMD (Single Program Multiple Data)Loop ParallelismMaster/WorkerFork/Join
Тесно пересекаются друг с другомДопускают комбинирование
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 8 / 66
Single Program Multiple Data
Все исполнители запускают одну программуИнициализацияПолучение уникального идентификатораВыполнение программы с учетом идентификатораРазное поведение: if(myId=...), for(..myId..)Распределение данных между исполнителямиИдентификаторы входят в правила разбиения данных(Операции обмена данными между исполнителями)Завершение программыРедукция результатов
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 9 / 66
Пример
1 #include <stdio.h>2
3 int main(int argc , char *argv []) {4 const int num_steps = 1E9;5 double x, sum = 0.0;6 const double step = 1.0/ num_steps;7 int i;8
9 for (i = 0; i < num_steps; i++) {10 x = (i+0.5)* step;11 sum += 4.0/(1.0+x*x);12 }13
14 printf("Pi = %.10f\n", step*sum);15 return 0;16 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 10 / 66
Пример (MPI)
1 int main (int argc , char *argv []) {2 // init variables ...3
4 MPI_Init (&argc , &argv);5 MPI_Comm_rank(MPI_COMM_WORLD , &my_id );6 MPI_Comm_size(MPI_COMM_WORLD , &numprocs );7
8 i_start = my_id * (num_steps/numprocs );9 i_end = i_start + (num_steps/numprocs );
10 if (my_id == (numprocs -1)) i_end = num_steps;11
12 for (i=i_start; i<i_end; i++)13 {14 x = (i+0.5)* step;15 sum += 4.0/(1.0+x*x);16 }17 sum *= step;18
19 MPI_Reduce (&sum , &pi, 1, MPI_DOUBLE , MPI_SUM , 0,MPI_COMM_WORLD );20
21 if (my_id == 0) printf("Pi = %.10f\n", pi);22
23 MPI_Finalize ();24
25 return 0;26 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 11 / 66
SPMD
ПлюсыНакладные расходы изолированы в начале и конце программыПоддержка сложной координации между исполнителямиВозможность использования в любых MIMD-системах
МинусыПрограмма сильно отличается от последовательной версииСложная логика распределения данных и балансировки нагрузкивредит ясности программыПлохо подходит для динамической балансировки нагрузки
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 12 / 66
Loop Parallelism
Вычислительно интенсивная часть алгоритма скрыта внутри циклаЕсть готовая последовательная программаИтерации внутри цикла являются независимымиТребуется распараллелить итерации, минимально модифицируяпри этом код исходной программы
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 13 / 66
Пример (OpenMP)
1 #include <stdio.h>2 #include <omp.h>3
4 int main(int argc , char *argv []) {5 const int num_steps = 1E9;6 double x, sum = 0.0;7 const double step = 1.0/ num_steps;8 int i;9
10 #pragma omp parallel for private(x) reduction (+:sum)11 for (i = 0; i < num_steps; i++) {12 x = (i+0.5)* step;13 sum += 4.0/(1.0+x*x);14 }15
16 printf("Pi = %.10f\n", step*sum);17 return 0;18 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 14 / 66
Loop Parallelism
ПлюсыМинимальная модификация последовательной программы ссохранением семантикиИнкрементальное распараллеливаниеЭквивалентность последовательной программе
МинусыОриентация только на системы с общей памятью (OpenMP)Оптимизация доступа к памяти может потребовать рефакторингаОграниченная масштабируемость
См. закон Амдала
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 15 / 66
Master/Worker
Требуется динамическая балансировка нагрузки между группойисполнителей
Сложность заданий изменяется сильно и непредсказуемоВычисления не сводятся к простым цикламВозможности отдельных исполнителей отличаются друг от другаи могут (непредсказуемо) изменяться во время вычислений
Большинство распределенных вычислительных систем
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 16 / 66
Master/Worker
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 17 / 66
Master/Worker - Часто встречающиеся вариации
Master становится worker-ом
Неявное распределение итераций в Loop Parallelism
Random work stealing
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 18 / 66
Master/Worker
ПлюсыАвтоматическая балансировка нагрузки, не требует явногоназначения исполнителейХорошо работает для задач с независимыми заданиямиПодходит для различных видов платформ
МинусыНеприменим для задач с зависимыми заданиями (требуетсякоординация и одновременное выполнение)
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 19 / 66
Рекурсивный Fork/Join
Задания создаются динамически, между заданиями существуютсложные зависимости
Divide and Conquer, рекурсивные данные
ПодходыКаждому заданию по исполнителю
Плохо масштабируетсяПул исполнителей
Общая очередь заданийWork stealing
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 20 / 66
Пример (Cilk)
1 cilk int fib (int n)2 {3 if (n < 2) return n;4 else5 {6 int x, y;7
8 x = spawn fib (n-1);9 y = spawn fib (n-2);
10
11 sync;12
13 return (x+y);14 }15 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 21 / 66
Знакомство с OpenMP
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 22 / 66
OpenMP (Open Multi-Processing)
Интерфейс параллельного программирования длямногопроцессорных систем с общей памятью
Поддерживает языки C/C++ и Fortran
Включает набор директив компилятора, библиотечных функций ипеременных окружения
Разрабатывается в рамках OpenMP Architecture Review Board с1997 года
http://www.openmp.org/OpenMP 2.5 (2005), OpenMP 3.0 (2008), OpenMP 3.1 (2011)
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 23 / 66
Реализации
OpenMP 2.5GCC 4.2 и вышеMicrosoft Visual C++ 2008 / 2010Intel C/C++ Compiler 10.1 и выше
OpenMP 3.0GCC 4.4 и вышеIntel C/C++ Compiler 11.0 и выше
См. http://openmp.org/wp/openmp-compilers/
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 24 / 66
Модель параллельного выполнения (fork/join)
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 25 / 66
Hello World
1 #include <omp.h>2 #include <stdio.h>3
4 int main(int argc , char **argv) {5 #pragma omp parallel6 printf("Hello , world.\n");7 return 0;8 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 26 / 66
Синтаксис прагм OpenMP для C/C++
#pragma omp directive [clause [clause] ... ]
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 27 / 66
Компиляция и запуск (GCC)
gcc(g++) hello.c -o hello./hello
1 Hello , world.
gcc(g++) -fopenmp hello.c -o hello./hello
1 Hello , world.2 Hello , world.3 ...
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 28 / 66
Visual Studio
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 29 / 66
Eclipse CDT + GCC
Необходимо указать флаг -fopenmp в GCC C Compiler (GCC CLinker ...) → Miscellaneous → Other flagsО.В. Сухорослов ()04 Параллельное программирование 16.03.2011 30 / 66
Hello World 2
1 #include <omp.h>2 #include <stdio.h>3
4 int main(int argc , char **argv) {5 int num_threads , thread_id;6
7 #pragma omp parallel private(thread_id)8 {9 thread_id = omp_get_thread_num ();
10 printf("%d: Hello , world .\n", thread_id );11
12 if (thread_id == 0)13 {14 num_threads = omp_get_num_threads ();15 printf("Number of threads = %d\n", num_threads );16 }17 }18 return 0;19 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 31 / 66
Без private(thread_id)
1 0: Hello , world.2 1: Hello , world.
1 1: Hello , world.2 Number of threads = 23 0: Hello , world.4 Number of threads = 2
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 32 / 66
Атрибуты видимости данных
private (list)firstprivate (list)lastprivate (list)threadprivate (list)shared (list)default (shared | none)
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 33 / 66
Число потоков
По умолчанию обычно равно числу процессоров
Может быть задано явноПеременная окружения OMP_NUM_THREADSФункция omp_set_num_threads()Директива #pragma omp parallel ... num_threads(N)
Может изменяться от секции к секции
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 34 / 66
Вычисление π
1 #include <stdio.h>2
3 int main(int argc , char *argv []) {4
5 const int num_steps = 1E9;6 double x, sum = 0.0;7 const double step = 1.0/ num_steps;8 int i;9
10 for (i = 0; i < num_steps; i++) {11 x = (i+0.5)* step;12 sum += 4.0/(1.0+x*x);13 }14
15 printf("Pi = %.10f\n", step*sum);16 return 0;17 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 35 / 66
Вариант 1 (SMPD)
1 #include <stdio.h>2 #include <omp.h>3
4 int main(int argc , char *argv []) {5 double start = omp_get_wtime ();6
7 const int num_steps = 1E9;8 double x, sum = 0.0;9 const double step = 1.0/ num_steps;
10 int i;11
12 int num_threads = omp_get_max_threads ();13 double sum_tmp[num_threads ];14
15 #pragma omp parallel private(i, x)16 {17 int id = omp_get_thread_num ();18 for (i = id; i < num_steps; i=i+num_threads) {19 x = (i -0.5)* step;20 sum_tmp[id] += 4.0/(1.0+x*x);21 }22 }23 for (i = 0; i < num_threads; i++) {24 sum += sum_tmp[i];25 }26
27 printf("Pi = %.10f\n", step*sum);28 printf("Time: %f\n", omp_get_wtime () - start);29 return 0;30 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 36 / 66
Вариант 2 (for, critical, nowait)
1 #pragma omp parallel2 {3 int id = omp_get_thread_num ();4 #pragma omp for private(x) nowait5 for (i = 0; i < num_steps; i++) {6 x = (i+0.5)* step;7 sum_tmp[id] += 4.0/(1.0+x*x);8 }9 #pragma omp critical
10 sum += sum_tmp[id];11 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 37 / 66
Ложное разделение данных (false sharing)
1 #pragma omp parallel for private(j,i)2 for(j=0; j<N; j++){3 for(i=0; i<M; i++){4 A[j] += work(i,j);5 }6 }
1 double temp;2
3 #pragma omp parallel for private(j,i,temp)4 for(j=0; j<N; j++){5 temp = 0.0;6 for(i=0; i<M;i++){7 temp += work(i,j);8 }9 A[j] += temp;
10 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 38 / 66
Вариант 3 (борьба с false sharing)
1 double sum_tmp[num_threads *8];2
3 #pragma omp parallel4 {5 int id = omp_get_thread_num ();6 int pos = id*8;7 #pragma omp for private(x) nowait8 for (i = 0; i < num_steps; i++) {9 x = (i+0.5)* step;
10 sum_tmp[pos] += 4.0/(1.0+x*x);11 }12 #pragma omp critical13 sum += sum_tmp[pos];14 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 39 / 66
Оптимизация при компиляции
gcc -O1(2,3) ...
gcc: компиляция на форсаже с турбо-наддувом (Крис Касперски)http://www.insidepro.com/kk/231/231r.shtml
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 40 / 66
Вариант 4 (for + reduction)
1 #include <stdio.h>2 #include <omp.h>3
4 int main(int argc , char *argv []) {5 double start = omp_get_wtime ();6
7 const int num_steps = 1E9;8 double x, sum = 0.0;9 const double step = 1.0/ num_steps;
10 int i;11
12 #pragma omp parallel for private(x) reduction (+:sum)13 for (i = 1; i <= num_steps; i++) {14 x = (i -0.5)* step;15 sum += 4.0/(1.0+x*x);16 }17
18 printf("Pi = %.10f\n", step*sum);19 printf("Time: %f\n", omp_get_wtime () - start);20 return 0;21 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 41 / 66
Допустимые операторы для reduction
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 42 / 66
Оптимизация циклов
Объединение циклов (укрупнение итераций)Развертывание вложенных циклов (увеличение кол-ва итераций)
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 43 / 66
Объединение циклов
1 for (i=0; i<N; i++) {2 FFT (Npoints , A, B);3 filter(Npoints , B, H);4 invFFT(Npoints , B, A);5 }6 for (i=0; i<N; i++) {7 FFT (Npoints , C, B);8 filter(Npoints , B, H);9 invFFT(Npoints , B, C);
10 }
1 for (i=0; i<N; i++) {2 FFT (Npoints , A, B);3 filter(Npoints , B, H);4 invFFT(Npoints , B, A);5 FFT (Npoints , C, B);6 filter(Npoints , B, H);7 invFFT(Npoints , B, C);8 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 44 / 66
Развертывание вложенных циклов
1 for (j=0; j<N; j++) {2 for (i=0; i<M; i++) {3 A[i][j] = work(i,j);4 }5 }
1 #pragma omp parallel for private(ij , j, i)2 for (ij=0; ij<N*M; ij++) {3 j = ij/N;4 i = ij%M;5 A[i][j] = work(i,j);6 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 45 / 66
Распределение итераций между потоками
Атрибут schedule(type, chunk)
Typestatic
Статическое распределение по принципу round-robindynamic
Динамическое распределение по принципу master-workerguided
Динамическое распределение с уменьшающимися порциямиruntime
Значение берется из переменной окружения OMP_SCHEDULE
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 46 / 66
Пример
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 47 / 66
Множество Мандельброта
Z (n + 1) = Z (n)2 + C , Z (0) = 0
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 48 / 66
Вариант 1 (static)
1 #pragma omp parallel for2 for(int pix=0; pix <num_pixels; ++pix)3 {4 const int x = pix%width , y = pix/width;5 complex c = begin + complex(x..., y..);6 int n = MandelbrotCalculate(c, maxiter );7 if(n == maxiter) n = 0;8 pixels[pix] = n;9 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 49 / 66
Вариант 2 (dynamic)
1 #pragma omp parallel for schedule(dynamic,16)2 for(int pix=0; pix <num_pixels; ++pix)3 {4 const int x = pix%width , y = pix/width;5 complex c = begin + complex(x..., y..);6 int n = MandelbrotCalculate(c, maxiter );7 if(n == maxiter) n = 0;8 pixels[pix] = n;9 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 50 / 66
Вариант 1* (static + chunk)
1 #pragma omp parallel for schedule(static,1)2 for(int pix=0; pix <num_pixels; ++pix)3 {4 const int x = pix%width , y = pix/width;5 complex c = begin + complex(x..., y..);6 int n = MandelbrotCalculate(c, maxiter );7 if(n == maxiter) n = 0;8 pixels[pix] = n;9 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 51 / 66
Вариант 3 (ordered)
1 #pragma omp parallel for ordered schedule(static,1)2
3 for(int pix=0; pix <num_pixels; ++pix)4 {5 const int x = pix%width , y = pix/width;6 complex c = begin + complex(x..., y..);7 int n = MandelbrotCalculate(c, maxiter );8 if(n == maxiter) n = 0;9
10 #pragma omp ordered11 {12 //print pixel on screen13 }14 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 52 / 66
Quicksort
1 void quicksort_serial(int arr[], int low , int high) {2 int i = low;3 int j = high;4 int y = 0;5 int z = arr[(low + high) / 2];6 do {7 while(arr[i] < z) i++;8 while(arr[j] > z) j--;9 if(i < j) {
10 y = arr[i];11 arr[i] = arr[j];12 arr[j] = y;13 i++;14 j--;15 }16 } while(i <= j);17
18 if(low < j)19 quicksort_serial(arr , low , j);20 if(i < high)21 quicksort_serial(arr , i, high);22 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 53 / 66
Вариант 1.1 (sections)
1 #pragma omp parallel sections2 {3 #pragma omp section4 {5 if(low < j)6 quicksort_nested(arr , low , j);7 }8 #pragma omp section9 {
10 if(i < high)11 quicksort_nested(arr , i, high);12 }13 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 54 / 66
Вариант 1.2 (sections + nested)
1 omp_set_nested (1);2 ...3
4 #pragma omp parallel sections5 {6 #pragma omp section7 {8 if(low < j)9 quicksort_nested(arr , low , j);
10 }11 #pragma omp section12 {13 if(i < high)14 quicksort_nested(arr , i, high);15 }16 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 55 / 66
Вариант 1.3 (max_active_levels)
1 omp_set_nested (1);2 omp_set_max_active_levels (4);3 ...4
5 #pragma omp parallel sections6 {7 #pragma omp section8 {9 if(low < j)
10 quicksort_nested(arr , low , j);11 }12 #pragma omp section13 {14 if(i < high)15 quicksort_nested(arr , i, high);16 }17 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 56 / 66
Вариант 1.4 (порог)
1 if (high -low < THRESHOLD ||2 (j-low < THRESHOLD || high -i < THRESHOLD )) {3 if(low < j)4 quicksort_nested(arr , low , j);5 if(i < high)6 quicksort_nested(arr , i, high);7 } else {8
9 #pragma omp parallel sections10 {11 #pragma omp section12 {13 if(low < j)14 quicksort_nested(arr , low , j);15 }16 #pragma omp section17 {18 if(i < high)19 quicksort_nested(arr , i, high);20 }21 }22 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 57 / 66
Вариант 2 (tasks, OpenMP 3.0)
1 #pragma omp parallel2 #pragma omp single3 {4 ...5
6 #pragma omp task7 {8 quicksort_tasks(arr , low , j);9 }
10
11 quicksort_tasks(arr , i, high);12
13 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 58 / 66
Адаптивная квадратура
1 long double quad(double left , double right ,2 long double f_left , long double f_right ,3 long double lr_area) {4 double mid = (left + right) / 2;5 long double f_mid = f(mid);6 long double l_area = (f_left+f_mid) * (mid -left) / 2;7 long double r_area = (f_mid+f_right) * (right -mid) / 2;8 if (fabs(( l_area+r_area) - lr_area) > EPSILON) {9 l_area = quad(left , mid , f_left , f_mid , l_area );
10 r_area = quad(mid , right , f_mid , f_right , r_area );11 }12 return (l_area + r_area );13 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 59 / 66
Адаптивная квадратура
1 long double quad_tasks(double left , double right ,2 long double f_left , long double f_right ,3 long double lr_area) {4 double mid = (left + right) / 2;5 long double f_mid = f(mid);6 long double l_area = (f_left+f_mid) * (mid -left) / 2;7 long double r_area = (f_mid+f_right) * (right -mid) / 2;8 if (fabs(( l_area+r_area) - lr_area) > EPSILON) {9 if (right - left < THRESHOLD) {
10 l_area = quad_tasks(left , mid , f_left , f_mid , l_area );11 r_area = quad_tasks(mid , right , f_mid , f_right , r_area );12 } else {13 #pragma omp task shared(l_area)14 l_area = quad_tasks(left , mid , f_left , f_mid , l_area );15 r_area = quad_tasks(mid , right , f_mid , f_right , r_area );16 #pragma omp taskwait17 }18 }19 return (l_area + r_area );20 }
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 60 / 66
Другие возможности
Синхронизацияcritical, atomic, ordered, barrier, nowait
flush
master
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 61 / 66
Накладные расходы
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 62 / 66
Привязка потоков к ядрам
OpenMP <3.1Переменные окружения, зависящие от компилятораgcc
export OMP_NUM_THREADS=8export GOMP_CPU_AFFINITY="0 1 2 3 4 5 6 7"
Windows APISetThreadAffinityMask(thread, mask)
OpenMP 3.1export OMP_PROC_BIND=true
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 63 / 66
Преимущества и недостатки OpenMP?
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 64 / 66
Домашнее задание (ДЗ №2, Задача 1)
Реализуйте параллельную версию алгоритма K-средних1 сиспользованием OpenMP
Измерьте время выполнения, ускорение и эффективность дляразличного числа потоков и размера задачи
Ускорение следует измерять относительно последовательнойпрограммы без OpenMPВремя работы последовательной программы на тестовом наборедолжно быть не менее 10 секундДля всех запусков с одним размером задачи следует использоватьодинаковый набор данных
Прокомментируйте полученные результаты
1http://en.wikipedia.org/wiki/K-means_clustering#Standard_algorithmО.В. Сухорослов ()04 Параллельное программирование 16.03.2011 65 / 66
Учебный кластер
Железо20 узлов (4 x Xeon E5645 2.40 GHz, 32 Gb RAM, 4 x 1 Tb)Дисковое пространство ∼ 4 TbGigabit Ethernet
Все что нужно для компиляции и запуска OpenMP-программgcc 4.4.3Запуск программ на узлах кластера через систему очередей
Для доступа к кластеру пришлите на [email protected]письмо:
Тема: "Учебный кластер"Содержание: Ваша фамилия в транслите с маленькой буквы(например, pupkin)
Инструкция по работе на кластереComing soon, см. на вики
О.В. Сухорослов ()04 Параллельное программирование 16.03.2011 66 / 66