'

Наиболее часто встречаемые ошибки в OpenMP-программах. Функциональная отладка OpenMP-программ

Понравилась презентация – покажи это...





Слайд 0

Наиболее часто встречаемые ошибки в OpenMP-программах. Функциональная отладка OpenMP-программ Технология параллельного программирования OpenMP Бахтин Владимир Александрович Ассистент кафедры системного программированния факультета ВМК, МГУ им. М. В. Ломоносова К.ф.-м.н., зав. сектором Института прикладной математики им М.В.Келдыша РАН


Слайд 1

Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Содержание Трудно обнаруживаемые ошибки типа race condition (конфликт доступа к данным). Ошибки типа deadlock (взаимная блокировка нитей). Ошибки, связанные с использованием неинициализированных переменных. Автоматизированный поиск ошибок в OpenMP-программах при помощи Intel Thread Checker (Intel Parallel Inspector) и Sun Studio Thread Analyzer (Oracle Solaris Studio).


Слайд 2

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Результат зависит от порядка выполнения команд. Требуется взаимное исключение критических интервалов. При взаимодействии через общую память нити должны синхронизовать свое выполнение. #pragma omp parallel { sum = sum + val; }


Слайд 3

Ошибка возникает при одновременном выполнении следующих условий: Две или более нитей обращаются к одной и той же ячейке памяти. По крайней мере, один из этих доступов к памяти является записью. Нити не синхронизируют свой доступ к данной ячейки памяти. При одновременном выполнении всех трех условий порядок доступа становится неопределенным. Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ


Слайд 4

Использование различных компиляторов (различных опций оптимизации, включение/отключение режима отладки при компиляции программы), применение различных стратегий планирования выполнения нитей в различных ОС, может приводить к тому, что в каких-то условиях (например, на одной вычислительной машине) ошибка не будет проявляться, а в других (на другой машине) – приводить к некорректной работе программы. От запуска к запуску программа может выдавать различные результаты в зависимости от порядка доступа. Отловить такую ошибку очень тяжело. Причиной таких ошибок, как правило являются: неверное определение класса переменной, отсутствие синхронизации. Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ


Слайд 5

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N float a[N], tmp; #pragma omp parallel { #pragma omp for for(int i=0; i<N;i++) { tmp= a[i]*a[i]; a[i]=1-tmp; } }


Слайд 6

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N float a[N], tmp; #pragma omp parallel { #pragma omp for for(int i=0; i<N;i++) { tmp= a[i]*a[i]; a[i]=1-tmp; } } #define N float a[N], tmp; #pragma omp parallel { #pragma omp for private(tmp) for(int i=0; i<N;i++) { tmp= a[i]*a[i]; a[i]=1-tmp; } }


Слайд 7

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ file1.c int counter = 0; #pragma omp threadprivate(counter) int increment_counter() { counter++; return(counter); } file2.c extern int counter; int decrement_counter() { counter--; return(counter); }


Слайд 8

Директива threadprivate threadprivate – переменные сохраняют глобальную область видимости внутри каждой нити #pragma omp threadprivate (Var) END PARALLEL PARALLEL END PARALLEL PARALLEL Var = 1 Var = 2 … = Var … = Var Если количество нитей не изменилось, то каждая нить получит значение, посчитанное в предыдущей параллельной области. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 9

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ file1.c int counter = 0; #pragma omp threadprivate(counter) int increment_counter() { counter++; return(counter); } file2.c extern int counter; #pragma omp threadprivate(counter) int decrement_counter() { counter--; return(counter); }


Слайд 10

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval; #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp for for(int i=0; i<N;i++) { maxval = Max(A[i],maxval); } }


Слайд 11

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval; #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp for for(int i=0; i<N;i++) { maxval = Max(A[i],maxval); } } #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval; #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp for for(int i=0; i<N;i++) { #pragma omp critical maxval = Max(A[i],maxval); } }


Слайд 12

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval; #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp for for(int i=0; i<N;i++) { maxval = Max(A[i],maxval); } } #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval; #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp barrier #pragma omp for for(int i=0; i<N;i++) { #pragma omp critical maxval = Max(A[i],maxval); } }


Слайд 13

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ void example(int n, int m, float *a, float *b, float *с, float *z) { int i; float sum = 0.0; #pragma omp parallel { #pragma omp for schedule(runtime) nowait for (i=0; i<m; i++) { c[i] = (a[i] + b[i]) / 2.0; } #pragma omp for schedule(runtime) nowait for (i=0; i<n; i++) z[i] = sqrt(c[i]); } }


Слайд 14

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ void example(int n, int m, float *a, float *b, float *с, float *z) { int i; float sum = 0.0; #pragma omp parallel { #pragma omp for schedule(runtime) for (i=0; i<m; i++) { c[i] = (a[i] + b[i]) / 2.0; } #pragma omp for schedule(runtime) nowait for (i=0; i<n; i++) z[i] = sqrt(c[i]); } }


Слайд 15

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ void example(int n, float *a, float *b, float *с, float *z) { int i; float sum = 0.0; #pragma omp parallel { #pragma omp for nowait reduction (+: sum) for (i=0; i<n; i++) { c[i] = (a[i] + b[i]) / 2.0; sum += c[i]; } #pragma omp for nowait for (i=0; i<n; i++) z[i] = sqrt(b[i]); #pragma omp master printf (“Sum of array C=%g\n”,sum); } }


Слайд 16

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ void example(int n, float *a, float *b, float *с, 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) nowait for (i=0; i<n; i++) z[i] = sqrt(b[i]); #pragma omp barrier #pragma omp master printf (“Sum of array C=%g\n”,sum); } }


Слайд 17

Распределение циклов с зависимостью по данным. Организация конвейерного выполнения цикла. for(int i = 1; i < N; i++) for(int j = 1; j < N; j++) a[i][j] = (a[i-1][j] + a[i][j-1] + a[i+1][j] + a[i][j+1]) / 4 Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 18

Распределение циклов с зависимостью по данным. Организация конвейерного выполнения цикла. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 19

001 Модель памяти в OpenMP Нить Кэш общих переменных Общая память Private-переменные Threadprivate-переменные 001 Нить Кэш общих переменных Private-переменные Threadprivate-переменные 001 Нить Кэш общих переменных Private-переменные Threadprivate-переменные Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 20

001 Нить 0 Общая память 001 Нить 1 static int i = 0; … = i + 1; i = i + 1; i = 0 i = 1 … = i + 2; // ? #pragma omp flush (i) #pragma omp flush (i) i = 1 i = 1 Модель памяти в OpenMP Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 21

Консистентность памяти в OpenMP Корректная последовательность работы нитей с переменной: Нить0 записывает значение переменной - write(var) Нить0 выполняет операцию синхронизации – flush (var) Нить1 выполняет операцию синхронизации – flush (var) Нить1 читает значение переменной – read (var) Директива flush: #pragma omp flush [(список переменных)] - для Си По умолчанию все переменные приводятся в консистентное состояние (#pragma omp 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, если изменилось состояние семафора. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 22

Распределение циклов с зависимостью по данным. Организация конвейерного выполнения цикла. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Москва, 2012 г.


Слайд 23

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define ITMAX 20 #define Max(a,b) ((a)>(b)?(a):(b)) double MAXEPS = 0.5; double grid[L][L], tmp[L][L],eps; #pragma omp parallel { for (int it=0;it<ITMAX; it++) { #pragma omp single eps= 0.; #pragma omp for for (int i=1; i<N-1; i++ ) for (int j=1; j<N-1; j++ ) { #pragma omp critical eps = Max(fabs(tmp[i][j]-grid[i][j]),eps); grid[i][j] = tmp[i][j]; } #pragma omp for for (int i=1; i<N-1; i++ ) for (int j=1; j<N-1; j++ ) tmp[i][j] = 0.25 * ( grid[i-1][j] + grid[i+1][j] + grid[i][j-1] + grid[i][j+1]); if (eps < MAXEPS) break; } }


Слайд 24

Конфликт доступа к данным Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define Max(a,b) ((a)>(b)?(a):(b)) double MAXEPS = 0.5; double grid[L][L], tmp[L][L],eps; #pragma omp parallel { for (int it=0;it<ITMAX; it++) { #pragma omp barrier #pragma omp single eps= 0.; #pragma omp for for (int i=1; i<N-1; i++ ) for (int j=1; j<N-1; j++ ) { #pragma omp critical eps = Max(fabs(tmp[i][j]-grid[i][j]),eps); grid[i][j] = tmp[i][j]; } #pragma omp for for (int i=1; i<N-1; i++ ) for (int j=1; j<N-1; j++ ) tmp[i][j] = 0.25 * ( grid[i-1][j] + grid[i+1][j] + grid[i][j-1] + grid[i][j+1]); if (eps < MAXEPS) break; } }


Слайд 25

Взаимная блокировка нитей Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N 10 int A[N],B[N], sum; #pragma omp parallel num_threads(10) { int iam=omp_get_thread_num(); if (iam ==0) { #pragma omp critical (update_a) #pragma omp critical (update_b) sum +=A[iam]; } else { #pragma omp critical (update_b) #pragma omp critical (update_a) sum +=B[iam]; } }


Слайд 26

Семафоры в OpenMP Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #include <omp.h> #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) int main () { omp_lock_t lck; float A[N], maxval; #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp barrier #pragma omp for for(int i=0; i<N;i++) { omp_set_lock(&lck); maxval = Max(A[i],maxval); omp_unset_lock(&lck); } } return 0; }


Слайд 27

Семафоры в OpenMP Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #include <omp.h> #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) int main () { omp_lock_t lck; float A[N], maxval; omp_init_lock(&lck); #pragma omp parallel { #pragma omp master maxval = 0.0; #pragma omp barrier #pragma omp for for(int i=0; i<N;i++) { omp_set_lock(&lck); maxval = Max(A[i],maxval); omp_unset_lock(&lck); } } omp_destroy_lock(&lck); return 0; }


Слайд 28

Взаимная блокировка нитей Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #pragma omp parallel { int iam=omp_get_thread_num(); if (iam ==0) { omp_set_lock (&lcka); omp_set_lock (&lckb); x = x + 1; omp_unset_lock (&lckb); omp_unset_lock (&lcka); } else { omp_set_lock (&lckb); omp_set_lock (&lcka); x = x + 2; omp_unset_lock (&lcka); omp_unset_lock (&lckb); } }


Слайд 29

Взаимная блокировка нитей Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #pragma omp parallel { int iam=omp_get_thread_num(); if (iam ==0) { omp_set_lock (&lcka); while (x<0); /*цикл ожидания*/ omp_unset_lock (&lcka); } else { omp_set_lock (&lcka); x++; omp_unset_lock (&lcka); } } }


Слайд 30

Неинициализированные переменные Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval, localmaxval; maxval = localmaxval = 0.0; #pragma omp parallel private (localmaxval) { #pragma omp for for(int i=0; i<N;i++) { localmaxval = Max(A[i],localmaxval); } #pragma omp critical maxval = Max(localmaxval,maxval); }


Слайд 31

Неинициализированные переменные Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ #define N 100 #define Max(a,b) ((a)>(b)?(a):(b)) float A[N], maxval, localmaxval; maxval = localmaxval = 0.0; #pragma omp parallel firstprivate (localmaxval) { #pragma omp for for(int i=0; i<N;i++) { localmaxval = Max(A[i],localmaxval); } #pragma omp critical maxval = Max(localmaxval,maxval); }


Слайд 32

Неинициализированные переменные Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ int tmp = 0; #pragma omp parallel { #pragma omp for firstprivate(tmp), lastprivate (tmp) for (int j = 0; j < 100; ++j) { if (j<98) tmp = j; } printf(“%d\n”, tmp); }


Слайд 33

Неинициализированные переменные Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ static int counter; #pragma omp threadprivate(counter) int main () { counter = 0; #pragma omp parallel { counter++; } }


Слайд 34

Неинициализированные переменные Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ static int counter; #pragma omp threadprivate(counter) int main () { counter = 0; #pragma omp parallel copyin (counter) { counter++; } }


Слайд 35

Автоматизированный поиск ошибок. Intel Thread Checker (Intel Parallel Inspector) Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ KAI Assure for Threads (Kuck and Associates) Анализ программы основан на процедуре инструментации. Инструментация – вставка обращений для записи действий, потенциально способных привести к ошибкам: работа с памятью, вызовы операций синхронизации и работа с потоками. Может выполняться: автоматически (бинарная инструментация) на уровне исполняемого модуля (а также dll-библиотеки) и/или по указанию программиста на уровне исходного кода (компиляторная инструментация Windows).


Слайд 36

Автоматизированный поиск ошибок. Intel Thread Checker Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Для каждой использованной в программе переменной сохраняется: адрес переменной; тип использования (read или write); наличие/отсутствие операции синхронизации; номер строки и имя файла; call stack. Инструментация программы + большой объем сохраняемой информации для каждого обращения = существенные накладные расходы и замедление выполнения программы.


Слайд 37

Пакет тестов SPLASH-2 (Stanford Parallel Applications for Shared Memory) на 4-х ядерной машине Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ http://iacoma.cs.uiuc.edu/iacoma-papers/asid06.pdf


Слайд 38

Автоматизированный поиск ошибок. Sun Thread Analyzer Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ Инструментация программы: cc -xinstrument=datarace -g -xopenmp=noopt test.c Накопление информации о программе: еxport OMP_NUM_THREADS=2 collect -r race ./a.out collect -r deadlock ./a.out collect -r all ./a.out Получение результатов анализа программы tha test.1.er => GUI er_print test.1.er => интерфейс командной строки


Слайд 39

Автоматизированный поиск ошибок. Sun Thread Analyzer Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ if (iam==0) { user_lock (); data = … … } else { user_lock (); … = data; … } if (iam==0) { ptr1 = mymalloc(sizeof(data_t)); ptr1->data = ... ... myfree(ptr1); } else { ptr2 = mymalloc(sizeof(data_t)); ptr2->data = ... ... myfree(ptr2); } Может выдавать сообщения об ошибках там где их нет


Слайд 40

Intel Thread Checker и Sun Thread Analyzer Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ http://www.fz-juelich.de/nic-series/volume38/terboven.pdf


Слайд 41


Слайд 42


Слайд 43


Слайд 44


Слайд 45


Слайд 46

Спасибо за внимание! Вопросы? Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ


Слайд 47

Отладка эффективности OpenMP-программ. Следующая тема Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ


Слайд 48

Бахтин В.А., кандидат физ.-мат. наук, заведующий сектором, Институт прикладной математики им. М.В.Келдыша РАН bakhtin@keldysh.ru Контакты Москва, 2012 г. Технология параллельного программирования OpenMP : Функциональная отладка OpenMP-программ


×

HTML:





Ссылка: