Главная /
Параллельное программирование с OpenMP
Параллельное программирование с OpenMP - ответы на тесты Интуит
В рамках курса проводится изучение основных возможностей стандарта OpenMP, необходимых для создания эффективных параллельных программ для многоядерных и многопоточных процессоров. Рассматриваются подходы для функциональной отладки OpenMP-программ, а также отладки эффективности.
Список вопросов:
- # Строгая модель консистентности памяти определяется следующим условием:
- # Последовательная модель консистентности памяти определяется следующим условием:
- # Причинная модель консистентности памяти определяется следующим условием:
- # PRAM модель консистентности памяти определяется следующим условием:
- # Процессорная модель консистентности памяти определяется следующим условием:
- # Слабая модель консистентности памяти определяется следующим условием:
- # Пусть W(x)a – операция записи в переменную x значения a. Пусть R(x)a – операция чтения переменной x, где a – прочитанное значение переменной x. Пусть S - операция синхронизации. Следующая последовательность событий: P1: W(x)aW(x)bSP2:R(x)aR(x)bSP3:R(x)bR(x)aS
- # Пусть W(x)a – операция записи в переменную x значения a. Пусть R(x)a – операция чтения переменной x, где a – прочитанное значение переменной x. Пусть S - операция синхронизации. Следующая последовательность событий: P1: W(x)aW(x)bSP2:SR(x)a
- # Пусть W(x)a – операция записи в переменную x значения a. Пусть R(x)a – операция чтения переменной x, где a – прочитанное значение переменной x. Следующая последовательность событий: P1: W(x)aW(x)cP2:R(x)aW(x)bP3:R(x)aR(x)cR(x)bP4:R(x)aR(x)bR(x)c
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int i; #pragma omp parallel { int tmp = 0; #pragma omp for private(tmp) for (i=0; i<N; i++) { tmp += i; } }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int i; int tmp = 0; #pragma omp parallel { #pragma omp for firstprivate(tmp) lastprivate(tmp) for (i=0; i<N; i++) { if (i != N - 1 ) tmp += i; } }
- # Определите класс по умолчанию для переменной numt: int i=0; int numt = omp_get_max_threads(); #pragma omp parallel for for(i=0; i< numt; i++) Work(i);
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int icount; #pragma omp threadprivate(icount) #pragma omp parallel { #pragma omp for for (icount=0; icount<N; icount++) { … } }
- # Найдите ошибку в следующем фрагменте программы: int i=0; int numt = omp_get_max_threads(); #pragma omp parallel default (none) private (i) { #pragma omp for for(i=0; i< numt; i++) Work(i); }
- # Использование операторов перехода (goto) в структурном блоке OpenMP возможно:
- # Использование оператора exit в структурном блоке OpenMP:
- # Исполняемыми директивами в OpenMP являются:
- # Параллельная область в OpenMP создается при помощи:
- # Функция omp_get_num_threads возвращает:
- # Функция omp_get_thread_num возвращает:
- # При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (+: sum), где переменная sum имеет тип integer, для каждой нити создается локальная копия переменной sum, начальное значение которой будет инициализировано:
- # При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (*: prod), где переменная prod имеет тип integer, для каждой нити создается локальная копия переменной prod, начальное значение которой будет инициализировано:
- # При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (-: sub), где переменная sub имеет тип integer, для каждой нити создается локальная копия переменной sub, начальное значение которой будет инициализировано:
- # Клауза copyin:
- # Клауза num_threads задает:
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int i; #pragma omp parallel firstprivate(i) lastprivate(i) { for (i=0; i<N; i++) { … } }
- # Рассмотрим фрагмент OpenMP-программы: #include <omp.h> int n=1; int main (void) { omp_set_nested(1); omp_set_dynamic(1); omp_set_num_threads(2); #pragma omp parallel if (n>10) {/*параллельная область*/ … } } Для выполнения параллельной области будет создана группа нитей, состоящая из:
- # Рассмотрим фрагмент OpenMP-программы: #include <omp.h> int main (void) { omp_set_nested(0); omp_set_max_active_levels(8); omp_set_num_threads(2); #pragma omp parallel { omp_set_num_threads(2); #pragma omp parallel { /*вложенная параллельная область*/ … } } } Для выполнения вложенной параллельной области будет создана группа нитей, состоящая из:
- # Пусть перед входом в параллельную область вызывается функция omp_set_num_threads. Пусть в директиве создания этой параллельной области указана клауза num_threads. Количество создаваемых нитей будет:
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i, j; #pragma omp for for (i=0; i<n; i++) { #pragma omp for for (j=0; j<n; j++) work(i, j); } }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i, j; #pragma omp for for (i=0; i<n; i++) { #pragma omp parallel { #pragma omp for shared (i,n) for (j=0; j<n; j++) work(i, j); } } }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i, j; #pragma omp for for (i=0; i<n; i++) { #pragma omp parallel private (i,n) { #pragma omp for for (j=0; j<n; j++) work(i, j); } } }
- # Найдите ошибку в следующем фрагменте программы: int i, j; #pragma omp parallel default(shared) { #pragma omp for collapse (3) for (i=0; i<n; i++) { for (j=0; j < n; j++) work(i, j); } }
- # Найдите ошибку в следующем фрагменте программы: int i, j; #pragma omp parallel default(shared) { #pragma omp for collapse (2) for (i=0; i<n; i++) { work_with_i (i); for (j=0; j < n; j++) work(i, j); } }
- # Найдите ошибку в следующем фрагменте программы: 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); } }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 float c[N]; float sum = 0.0; #pragma omp parallel shared(sum, c) { #pragma omp for reduction (+: sum) nowait for (int i=0; i<N; i++) { sum += c[i]; } #pragma omp single printf (“Sum of array=%4.2f\n”, sum); }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int i; #pragma omp parallel { #pragma omp for firstprivate(i) lastprivate(i) for (i=0; i<N; i++) { … } #pragma omp single printf (“Number of iteration=%d\n”, i); }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int i; #pragma omp parallel { #pragma omp for private(i) lastprivate(i) for (i=0; i<N; i++) { … } #pragma omp single printf (“Number of iteration=%d\n”, i); }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i; #pragma omp for lastprivate(i) for (i=0; i!=n; i++) { work(i); } }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i; #pragma omp for lastprivate(i) for (i=0; i<n; i++) { i+=2; work(i); } }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i; #pragma omp for lastprivate(i) for (i=0; i<n + omp_get_thread_num (); i++) { work(i); } }
- # Способ распределения витков цикла между нитями группы задается при помощи клаузы schedule(<алгоритм планирования>[,<число итераций>]). Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i; #pragma omp for schedule(static, omp_get_thread_num()) for (i=0; i<n; i++) { work(i); } }
- # Способ распределения витков цикла между нитями группы задается при помощи клаузы schedule(<алгоритм планирования>[,<число итераций>]). Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i; #pragma omp for schedule(dynamic, omp_get_thread_num()) for (i=0; i<n; i++) { work(i); } }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel default(shared) { int i; #pragma omp for schedule(dynamic) for (i=0; i<n; i++) { #pragma omp ordered printf("iteration %d\n", i); } }
- # Директива master
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N]; #pragma omp parallel default(shared) { int i; ..…#pragma omp master for (i=0; i<N; i++) { A[i]=0; } #pragma omp for for (i=0; i<N; i++) B[i]=A[i]; }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N]; #pragma omp parallel default(shared) { int i; ..…#pragma omp master for (i=0; i<N; i++) { A[i]=0; } #pragma omp single B[N-1]=A[N-1]; }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N]; #pragma omp parallel default(shared) { int i; #pragma omp master for (i=0; i<N; i++) { A[i]=0; } #pragma omp barrier B[N-1]=B[N-1] + A[N-1]; }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N],tmp; #pragma omp parallel default(shared) num_threads(10) { int iam=omp_get_thread_num(); tmp=A[iam]; B[iam]=tmp; }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N]; #pragma omp parallel default(shared) num_threads(10) { int iam=omp_get_thread_num(); int tmp; tmp=A[iam]; B[iam]=tmp; }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N], sum; #pragma omp parallel default(shared) num_threads(10) { int iam=omp_get_thread_num(); if (A[iam] > 0) { #pragma omp critical (update_a) sum +=A[iam]; } if (B[iam] > 0) { #pragma omp critical (update_b) sum +=B[iam]; } }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N],B[N], sum; #pragma omp parallel default(shared) 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]; } }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N], sum; #pragma omp parallel default(shared) num_threads(10) { int iam=omp_get_thread_num(); #pragma omp critical (update_a) #pragma omp critical (update_a) sum +=A[iam]; }
- # Найдите ошибку в следующем фрагменте программы: int numt=0; #pragma omp parallel { #pragma omp master { #pragma omp critical { numt=omp_get_num_threads(); } #pragma omp barrier } }
- # Найдите ошибку в следующем фрагменте программы: int numt=0; #pragma omp parallel { #pragma omp single { #pragma omp critical { numt=omp_get_num_threads(); } #pragma omp barrier } }
- # Найдите ошибку в следующем фрагменте программы: int numt=0; #pragma omp parallel { #pragma omp critical { numt=omp_get_num_threads(); #pragma omp barrier #pragma omp flush (numt) } }
- # Найдите ошибку в следующем фрагменте программы: #include <math.h> double x=1024.0; int n=1024; #pragma omp parallel { #pragma omp atomic x+=sqrt(x); #pragma omp atomic n&=0177; }
- # Найдите ошибку в следующем фрагменте программы: #include <math.h> double x=1024.0; int n=1024; #pragma omp parallel { #pragma omp atomic x=sqrt(x); #pragma omp atomic n&=0177; }
- # Найдите ошибку в следующем фрагменте программы: int x=0; omp_lock_t lcka, lckb; omp_init_lock (&lcka); omp_init_lock (&lckb); #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); } } } omp_destroy_lock (&lcka); omp_destroy_lock (&lckb);
- # Определите способ распределения витков цикла между нитями для следующего фрагмента программы: #define N 100 void work(int i); int main () { #pragma omp parallel { #pragma omp for for (int i=0;i<N;i++) work (i); } }
- # Определите способ распределения витков цикла между нитями для следующего фрагмента программы: #define N 100 #include "omp.h" void work(int i); int main () { #pragma omp parallel { omp_set_schedule (omp_sched_dynamic); #pragma omp for schedule(static) for (int i=0;i<N;i++) work (i); } }
- # Определите способ распределения витков цикла между нитями для следующего фрагмента программы: #define N 100 #include "omp.h" void work(int i); int main () { #pragma omp parallel { omp_set_schedule (omp_sched_static); #pragma omp for schedule(dynamic) for (int i=0;i<N;i++) work (i); } }
- # Определите способ распределения витков цикла между нитями для следующего фрагмента программы: #define N 100 #include "omp.h" void work(int i); int main () { #pragma omp parallel { omp_set_schedule (omp_sched_static); #pragma omp for for (int i=0;i<N;i++) work (i); } }
- # Определите способ распределения витков цикла между нитями для следующего фрагмента программы: #define N 100 #include "omp.h" void work(int i); int main () { #pragma omp parallel { omp_set_schedule (omp_sched_dynamic); #pragma omp for for (int i=0;i<N;i++) work (i); } }
- # Определите способ распределения витков цикла между нитями для следующего фрагмента программы: #define N 100 #include "omp.h" void work(int i); int main () { #pragma omp parallel { omp_set_schedule (omp_sched_guided); #pragma omp for for (int i=0;i<N;i++) work (i); } }
- # Определите количество нитей, между которыми будет распределена работа в параллельной области: #define N 100 #include "omp.h" void work(int i); int main () { omp_set_num_threads(2); #pragma omp parallel num_threads(4) { #pragma omp for for (int i=0;i<N;i++) work (i); } }
- # Определите количество нитей, между которыми будет распределена работа в параллельной области: #include "omp.h" void work(int i); int main () { int n; n=10; omp_set_num_threads(2); #pragma omp parallel num_threads(4) if (n>20) { #pragma omp for for (int i=0;i<n;i++) work (i); } }
- # Определите количество нитей, между которыми будет распределена работа в параллельной области: #include "omp.h" void work(int i); int main () { int n; n=10; #pragma omp parallel num_threads(4) if (n>20) { #pragma omp for for (int i=0;i<n;i++) work (i); } }
- # Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм. #include <stdio.h> #include "omp.h" int counter; int main() { counter=0; omp_set_nested(0); #pragma omp parallel num_threads(2) { if (omp_get_thread_num() == 0) { #pragma omp parallel num_threads(2) { #pragma omp atomic counter++; } } } printf("Counter=%d\n",counter); } Определите значение переменной counter по завершении выполнения этой программы:
- # Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм. #include <stdio.h> #include "omp.h" int counter; int main() { counter=0; omp_set_nested(1); #pragma omp parallel num_threads(2) { if (omp_get_thread_num() == 0) { #pragma omp parallel num_threads(2) { #pragma omp atomic counter++; } } } printf("Counter=%d\n",counter); } Определите значение переменной counter по завершении выполнения этой программы:
- # Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм. #include <stdio.h> #include "omp.h" int counter; int main() { counter=0; omp_set_nested(0); #pragma omp parallel num_threads(2) { #pragma omp parallel num_threads(2) { #pragma omp atomic counter++; } } printf("Counter=%d\n",counter); } Определите значение переменной counter по завершении выполнения этой программы:
- # Определите значение переменной team_size по завершении выполнения следующей программы: #include <stdio.h> #include "omp.h" int main() { int team_size; team_size=omp_get_team_size(omp_get_level ()); printf("Team Size=%d\n",team_size); }
- # Определите значение переменной team_size по завершении выполнения следующей программы: #include <stdio.h> #include "omp.h" int main() { int team_size; team_size=0; #pragma omp parallel num_threads(2) { if (omp_get_thread_num() == 0) { team_size=omp_get_team_size(omp_get_level ()); } } printf("Team Size=%d\n",team_size); }
- # Определите значение переменной team_size по завершении выполнения следующей программы: #include <stdio.h> #include "omp.h" int main() { int team_size; team_size=0; #pragma omp parallel num_threads(2) { if (omp_get_thread_num() == 0) { team_size=omp_get_team_size(0); } } printf("Team Size=%d\n",team_size); }
- # Найдите ошибку в следующем фрагменте программы: #define N 1000 int main (void){ 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 1000 int main (void){ float a[N]; #pragma omp parallel { #pragma omp for for(int i=0; i<N;i++) { float tmp; tmp= a[i]*a[i]; a[i]=1-tmp; } } }
- # Найдите ошибку в следующем фрагменте программы: #define N 1000 int main (void){ float a[N], tmp; #pragma omp parallel { int i; #pragma omp for private(i) for(i=0; i<N;i++) { tmp= a[i]*a[i]; a[i]=1-tmp; } } }
- # Найдите ошибку в следующем фрагменте программы: int main (void){ int a, i; #pragma omp parallel shared(a) private(i) { #pragma omp master a = 0; #pragma omp for reduction(+:a) for (i = 0; i < 10; i++) { a += i; } } }
- # int main (void){ int a, i; #pragma omp parallel shared(a) private(i) { #pragma omp single a = 0; #pragma omp for for (i = 0; i < 10; i++) { a += i; } } }
- # Найдите ошибку в следующем фрагменте программы: int main (void){ int a; #pragma omp parallel private(a) { #pragma omp single a = 0; #pragma omp for reduction(+:a) for (int i = 0; i < 10; i++) { a += i; } } }
- # Найдите ошибку в следующем фрагменте программы: #include <omp.h> int numproc; #pragma omp threadprivate(numproc) int main (void){ numproc=omp_get_num_procs(); #pragma omp parallel { if (numproc < 4) do_small_work(); else do_big_work (); } }
- # Найдите ошибку в следующем фрагменте программы: #include <omp.h> int main (void){ #pragma omp parallel { int numt; #pragma omp single numt=omp_get_num_threads(); if (numt < 4) do_small_work(); else do_big_work (); } }
- # Найдите ошибку в следующем фрагменте программы: #define N 1000 float a[N], b[N]; int main (void){ int i; #pragma omp parallel { #pragma omp for for (i=0; i<N-1; i++) { a[i] = b[i] + b[i+1]; } a[i]=b[i]; } }
- # Найдите ошибку в следующем фрагменте программы: #pragma omp parallel { int me; me = omp_get_thread_num (); if (me == 0) goto Master; #pragma omp barrier Master: #pragma omp single }
- # Найдите ошибку в следующем фрагменте программы: #define N 10 int A[N], sum; #pragma omp parallel default(shared) num_threads(10) { int iam=omp_get_thread_num(); #pragma omp critical (update_a) #pragma omp critical (update_a) sum +=A[iam]; }
- # #define N 10 int A[N],B[N], sum; #pragma omp parallel default(shared) 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]; } }
- # Поиск ошибок в OpenMP-программе, выполняемый Intel Thread Checker, основан на:
- # Поиск ошибок в OpenMP-программе, выполняемый Sun Thread Analyzer, основан на:
- # Intel Thread Checker:
- # Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (8); #pragma omp parallel { #pragma omp for schedule (runtime) for(int i=0; i<100;i++) { sleep (i*msec); } } }
- # Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (8); #pragma omp parallel { #pragma omp for schedule (runtime) for(int i=0; i<100;i++) { sleep ((100-i)*msec); } } }
- # Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения: #include <omp.h> #include<stdio.h> #include<stdlib.h> #include <time.h> #define msec 1000 int main (void){ srand (time(NULL)); omp_set_num_threads (8); #pragma omp parallel { #pragma omp for schedule (runtime) for(int i=0; i<100;i++) { sleep (rand()*msec); } } }
- # Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (8); #pragma omp parallel { #pragma omp for schedule (runtime) for(int i=0; i<80;i++) { sleep (msec); } } }
- # Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (4); #pragma omp parallel { #pragma omp for schedule (runtime) for(int i=0; i<40;i++) { sleep (msec); } } }
- # Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (4); #pragma omp parallel { #pragma omp for schedule (runtime) for(int i=0; i<60;i++) { sleep (msec); } } }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <stdio.h> #define N 100 float c[N]; float sum = 0.0; int main (void) { omp_set_num_threads (8); #pragma omp parallel shared(sum, c) { #pragma omp for for (int i=0; i<N; i++) { #pragma omp critical sum += c[i]; } } printf (“Sum of array=%4.2f\n”, sum); }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <stdio.h> #define N 100 int c[N]; int val = 0; int main (void) { omp_set_num_threads (8); #pragma omp parallel shared(val, c) { #pragma omp for for (int i=0; i<N; i++) { #pragma omp critical val ^= c[i]; } } printf (“Result=%d\n”, var); }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <stdio.h> #define N 100 int c[N]; int val= 1; int main (void) { omp_set_num_threads (8); #pragma omp parallel shared(val, c) { #pragma omp for for (int i=0; i<N; i++) { #pragma omp critical val = val && (c[i]<100); } } printf (“Result=%4.2f\n”, val); }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (8); #pragma omp parallel { #pragma omp for for(int i=0; i<80;i++) { sleep (i*msec); } #pragma omp for for(int i=0; i<80;i++) { sleep ((80-i)*msec); } } }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #define N 100 omp_set_num_threads (4); #pragma omp parallel shared(a,b,c,x,y,z) { #pragma omp for for (int i=0; i<N; i++) { z[i] = x[i] + y[i]; } #pragma omp for for (int i=0; i<N; i++) { a[i] = b[i] + c[i]; } }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #define N 80 omp_set_num_threads (8); #pragma omp parallel shared(a,b,c,x,y,z) { #pragma omp for for (int i=0; i<N; i++) { z[i] = x[i] + y[i]; } #pragma omp for for (int i=0; i<N; i++) { a[i] = b[i] + c[i]; } }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ int i; omp_set_num_threads (8); #pragma omp parallel for for (i=0; i<80; i++) sleep (msec); #pragma omp parallel for for (i=0; i<80; i++) sleep (msec); }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (8); #pragma omp parallel for for (int i=0; i<5; i++) for (int j=0; j<5; j++) sleep (msec); }
- # Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы: #include <omp.h> #include <unistd.h> #define msec 1000 int main (void){ omp_set_num_threads (8); for (int i=0; i<80; i++) #pragma omp parallel for for (int j=0; j<80; j++) sleep (msec); }
- # Директива SHARABLE в технологии Intel Cluster OpenMP:
- # Для выделения памяти для SHARABLE-переменных в технологии Intel Cluster OpenMP требуется использовать:
- # Переменные, которые разделяются нитями, и доступ к которым обрабатывается в технологии Intel Cluster OpenMP механизмом DSM, могут быть заданы при помощи:
- # Использование технологии Intel Cluster OpenMP целесообразно:
- # При использовании технологии Intel Cluster OpenMP программист:
- # Реализация технологии Intel Cluster OpenMP стала возможной, поскольку в OpenMP используется:
- # Технология OpenMP по сравнению с MPI имеет следующие преимущества (отметьте все подходящие варианты):
- # При использовании гибридной модели параллельного программирования MPI/OpenMP:
- # При использовании гибридной модели параллельного программирования DVM/OpenMP:
- # Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, вычисляющей число Пи: #include <mpi.h> #include <omp.h> #define num_steps 100000 void main (int argc, char *argv[]) { double pi, step, sum = 0.0 ; step = 1.0/(double) num_steps ; #pragma omp parallel { int numprocs, myid, mysteps; MPI_Init(&argc, &argv) ; MPI_Comm_Rank(MPI_COMM_WORLD, &myid) ; MPI_Comm_Size(MPI_COMM_WORLD, &numprocs) ; mysteps = num_steps/numprocs ; #pragma omp for reduction(+:sum) for (int i=myid*mysteps; i<(myid+1)*mysteps ; i++){ double x = (i+0.5)*step; sum += 4.0*step/(1.0+x*x); } MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); } MPI_Finalize(); }
- # Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, вычисляющей число Пи: #include <mpi.h> #include <omp.h> #define num_steps 100000 void main (int argc, char *argv[]) { int numprocs, myid, mysteps; double pi, step, sum = 0.0 ; MPI_Init(&argc, &argv) ; MPI_Comm_Rank(MPI_COMM_WORLD, &myid) ; MPI_Comm_Size(MPI_COMM_WORLD, &numprocs) ; step = 1.0/(double) num_steps ; mysteps = num_steps/numprocs ; #pragma omp parallel shared(myid, mysteps, step) reduction(+:sum) { #pragma omp for for (int i=myid*mysteps; i<(myid+1)*mysteps ; i++){ double x = (i+0.5)*step; sum += 4.0*step/(1.0+x*x); } MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); } MPI_Finalize(); }
- # Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, вычисляющей число Пи: #include <mpi.h> #include <omp.h> #define num_steps 100000 void main (int argc, char *argv[]) { int numprocs, myid, mysteps; double pi, step, sum = 0.0 ; MPI_Init(&argc, &argv) ; MPI_Comm_Rank(MPI_COMM_WORLD, &myid) ; MPI_Comm_Size(MPI_COMM_WORLD, &numprocs) ; step = 1.0/(double) num_steps ; mysteps = num_steps/numprocs ; #pragma omp parallel shared(myid, mysteps, step) { #pragma omp for reduction(+:sum) for (int i=myid*mysteps; i<(myid+1)*mysteps ; i++){ double x = (i+0.5)*step; sum += 4.0 /(1.0+x*x); } sum *= step ; } MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Finalize(); }
- # Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, реализующей метод релаксации Якоби: int jacobi(int p, int id, int my_rows, double **u, double **w) { double diff, global_diff, tdiff; int i,j,it; MPI_Status status; it=0; for(;;) { if (id>0) MPI_Send (u[1], N, MPI_DOUBLE, id-1, 0, MPI_COMM_WORLD); if (id<p-1) { MPI_Send (u[my_rows-2], N, MPI_DOUBLE, id+1, 0, MPI_COMM_WORLD); MPI_Recv (u[my_rows-1], N, MPI_DOUBLE, id+1, 0, MPI_COMM_WORLD, &status); } if (id>0) MPI_Recv (u[0], N, MPI_DOUBLE, id-1, 0, MPI_COMM_WORLD, &status); diff=0.0; #pragma omp parallel private (i,j,tdiff) { tdiff=0.0; #pragma omp for for (i=1; i<my_rows; i++) for (j=1; j<N-1; j++) { w[i][j]=(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1])/4.0; if (fabs(w[i][j]-u[i][j]) >tdiff) tdiff=fabs(w[i][j]-u[i][j]); } #pragma omp for nowait for (i=1; i<my_rows; i++) for (j=1; j<N-1; j++) u[i][j]=w[i][j]; if (tdiff > diff) diff=tdiff; } MPI_Allreduce (&diff, &global_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); if (global_diff <= EPSILON) break; it++; } return it; }
- # Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, реализующей метод релаксации Якоби: int jacobi(int p, int id, int my_rows, double **u, double **w) { double diff, global_diff, tdiff; int i,j,it; MPI_Status status; it=0; for(;;) { if (id>0) MPI_Send (u[1], N, MPI_DOUBLE, id-1, 0, MPI_COMM_WORLD); if (id<p-1) { MPI_Send (u[my_rows-2], N, MPI_DOUBLE, id+1, 0, MPI_COMM_WORLD); MPI_Recv (u[my_rows-1], N, MPI_DOUBLE, id+1, 0, MPI_COMM_WORLD, &status); } if (id>0) MPI_Recv (u[0], N, MPI_DOUBLE, id-1, 0, MPI_COMM_WORLD, &status); diff=0.0; #pragma omp parallel private (i,j,tdiff) { tdiff=0.0; #pragma omp for for (i=1; i<my_rows; i++) for (j=1; j<N-1; j++) { w[i][j]=(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1])/4.0; if (fabs(w[i][j]-u[i][j]) >tdiff) tdiff=fabs(w[i][j]-u[i][j]); } #pragma omp for nowait for (i=1; i<my_rows; i++) for (j=1; j<N-1; j++) u[i][j]=w[i][j]; #pragma omp critical if (tdiff > diff) diff=tdiff; MPI_Allreduce (&diff, &global_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); } if (global_diff <= EPSILON) break; it++; } return it; }
- # Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, реализующей метод релаксации Якоби: int jacobi(int p, int id, int my_rows, double **u, double **w) { double diff, global_diff, tdiff; int i,j,it; MPI_Status status; it=0; #pragma omp parallel private (i,j,tdiff) { for(;;) { #pragma omp master { diff=0.0; if (id>0) MPI_Send (u[1], N, MPI_DOUBLE, id-1, 0, MPI_COMM_WORLD); if (id<p-1) { MPI_Send (u[my_rows-2], N, MPI_DOUBLE, id+1, 0, MPI_COMM_WORLD); MPI_Recv (u[my_rows-1], N, MPI_DOUBLE, id+1, 0, MPI_COMM_WORLD, &status); } if (id>0) MPI_Recv (u[0], N, MPI_DOUBLE, id-1, 0, MPI_COMM_WORLD, &status); } /*end of master*/ tdiff=0.0; #pragma omp for for (i=1; i<my_rows; i++) for (j=1; j<N-1; j++) { w[i][j]=(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1])/4.0; if (fabs(w[i][j]-u[i][j]) >tdiff) tdiff=fabs(w[i][j]-u[i][j]); } #pragma omp for nowait for (i=1; i<my_rows; i++) for (j=1; j<N-1; j++) u[i][j]=w[i][j]; #pragma omp critical if (tdiff > diff) diff=tdiff; #pragma omp barrier #pragma omp single { it++; MPI_Allreduce (&diff, &global_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); } /*end of single*/ if (global_diff <= EPSILON) break; } return it; }