База ответов ИНТУИТ

Параллельное программирование с OpenMP - ответы

Количество вопросов - 119

Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм.
#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 по завершении выполнения этой программы:

Способ распределения витков цикла между нитями группы задается при помощи клаузы 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);    }}

Найдите ошибку в следующем фрагменте программы:
#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 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;          }     }}

Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#include <omp.h>#include <unistd.h>#define msec 1000int main (void){     omp_set_num_threads (4);     #pragma omp parallel     {           #pragma omp for schedule (runtime)           for(int i=0; i<40;i++) {                   sleep (msec);           }     }}

Найдите ошибку в следующем фрагменте программы:
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);         }     }

Параллельная область в OpenMP создается при помощи:

При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (-: sub), где переменная sub имеет тип integer, для каждой нити создается локальная копия переменной sub, начальное значение которой будет инициализировано:

Найдите ошибку в следующем фрагменте программы:
#pragma omp parallel default(shared){    int i;    #pragma omp for lastprivate(i)    for (i=0; i<n + omp_get_thread_num (); i++) {            work(i);    }}

Определите значение переменной 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);}

Пусть W(x)a – операция записи в переменную x значения a. Пусть R(x)a – операция чтения переменной x, где a – прочитанное значение переменной x. Следующая последовательность событий:
P1: W(x)aW(x)c
P2:R(x)aW(x)b
P3:R(x)aR(x)cR(x)b
P4:R(x)aR(x)bR(x)c

Найдите ошибку в следующем фрагменте программы:
#define N 1000float 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];     }}

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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 1000int 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;            }     }}

Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, вычисляющей число Пи:
#include <mpi.h>#include <omp.h>#define num_steps 100000void 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();}

Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#include <omp.h>#include <unistd.h>#define msec 1000int 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);}

Найдите ошибку в следующем фрагменте 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;}

Поиск ошибок в OpenMP-программе, выполняемый Sun Thread Analyzer, основан на:

Найдите ошибку в следующем фрагменте программы:
#pragma omp parallel{       int me;       me = omp_get_thread_num ();       if (me == 0) goto Master;       #pragma omp barrierMaster:       #pragma omp single}

Использование операторов перехода (goto) в структурном блоке OpenMP возможно:

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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;    }}

Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#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);    }}

Определите количество нитей, между которыми будет распределена работа в параллельной области:
#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);    }}

Использование технологии Intel Cluster OpenMP целесообразно:

Процессорная модель консистентности памяти определяется следующим условием:

Причинная модель консистентности памяти определяется следующим условием:

Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#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);    }}

Найдите ошибку в следующем фрагменте программы:
#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);    }}

Клауза copyin:

Найдите ошибку в следующем фрагменте программы:
#define N 10float 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);}

Строгая модель консистентности памяти определяется следующим условием:

Слабая модель консистентности памяти определяется следующим условием:

Пусть W(x)a – операция записи в переменную x значения a. Пусть R(x)a – операция чтения переменной x, где a – прочитанное значение переменной x. Пусть S - операция синхронизации. Следующая последовательность событий:
P1: W(x)aW(x)bS
P2:SR(x)a

Найдите ошибку в следующем фрагменте программы:
#define N 10int i;#pragma omp parallel{     int tmp = 0;    #pragma omp for private(tmp)    for (i=0; i<N; i++) {        tmp += i;    }}

Определите класс по умолчанию для переменной numt:
int i=0;int numt = omp_get_max_threads();#pragma omp parallel forfor(i=0; i< numt; i++)       Work(i);

Исполняемыми директивами в OpenMP являются:

Клауза num_threads задает:

Рассмотрим фрагмент 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              { /*вложенная параллельная область*/             …              }         }}
Для выполнения вложенной параллельной области будет создана группа нитей, состоящая из:

Найдите ошибку в следующем фрагменте программы:
#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);       }    }}

Найдите ошибку в следующем фрагменте программы:
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);         }     }

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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);}

Способ распределения витков цикла между нитями группы задается при помощи клаузы 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);    }}

Директива master

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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 10int 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];      }}

Найдите ошибку в следующем фрагменте программы:
int numt=0;#pragma omp parallel{      #pragma omp master      {          #pragma omp critical          {                numt=omp_get_num_threads();          }          #pragma omp barrier       }}

Найдите ошибку в следующем фрагменте программы:
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#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);    }}

Определите значение переменной 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);}

Найдите ошибку в следующем фрагменте программы:
#define N 1000int 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;            }     }}

Найдите ошибку в следующем фрагменте программы:
#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 ();     }}

#define N 10int 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, основан на:

Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#include <omp.h>#include <unistd.h>#define msec 1000int 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>#define N 100int 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);}

Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#define N 80omp_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];    }}

Для выделения памяти для SHARABLE-переменных в технологии Intel Cluster OpenMP требуется использовать:

Технология OpenMP по сравнению с MPI имеет следующие преимущества (отметьте все подходящие варианты):

Найдите ошибку в следующем фрагменте 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;}

При использовании гибридной модели параллельного программирования DVM/OpenMP:

Определите количество нитей, между которыми будет распределена работа в параллельной области:
#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 <omp.h>#include <unistd.h>#define msec 1000int main (void){     omp_set_num_threads (4);     #pragma omp parallel     {           #pragma omp for schedule (runtime)           for(int i=0; i<60;i++) {                   sleep (msec);           }     }}

Рассмотрим фрагмент 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) {/*параллельная область*/ … }}Для выполнения параллельной области будет создана группа нитей, состоящая из:

При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (+: sum), где переменная sum имеет тип integer, для каждой нити создается локальная копия переменной sum, начальное значение которой будет инициализировано:

Найдите ошибку в следующем фрагменте программы:
#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);       }    }}

Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#include <omp.h>#include <unistd.h>#define msec 1000int 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);           }     }}

Найдите ошибку в следующем фрагменте программы:
#pragma omp parallel default(shared){    int i;    #pragma omp for lastprivate(i)    for (i=0; i!=n; i++) {            work(i);    }}

Intel Thread Checker:

Последовательная модель консистентности памяти определяется следующим условием:

Найдите ошибку в следующем фрагменте программы:
#define N 1000int 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;            }     }}

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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 10int 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;}

Найдите ошибку в следующем фрагменте 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;}

Найдите ошибку в следующем фрагменте программы:
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);         }     }

Пусть W(x)a – операция записи в переменную x значения a. Пусть R(x)a – операция чтения переменной x, где a – прочитанное значение переменной x. Пусть S - операция синхронизации. Следующая последовательность событий:
P1: W(x)aW(x)bS
P2:R(x)aR(x)bS
P3:R(x)bR(x)aS

Найдите ошибку в следующем фрагменте программы:
#define N 10int icount;#pragma omp threadprivate(icount)#pragma omp parallel{   #pragma omp for    for (icount=0; icount<N; icount++) {    …    }}

Директива SHARABLE в технологии Intel Cluster OpenMP:

Функция omp_get_thread_num возвращает:

Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#include <omp.h>#include<stdio.h>#include<stdlib.h>#include <time.h>#define msec 1000int 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);             }     }}

Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#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);    }}

PRAM модель консистентности памяти определяется следующим условием:

Использование оператора exit в структурном блоке OpenMP:

Найдите ошибку в следующем фрагменте программы:
#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 schedule(dynamic)    for (i=0; i<n; i++) {        #pragma omp ordered            printf("iteration %d\n", i);     }}

Найдите ошибку в следующем фрагменте программы:
int numt=0;#pragma omp parallel{      #pragma omp single      {          #pragma omp critical          {                numt=omp_get_num_threads();          }          #pragma omp barrier       }}

Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм.
#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 <omp.h>#include <unistd.h>#define msec 1000int 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 <stdio.h>#define N 100float 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 <unistd.h>#define msec 1000int 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);           }     }}

Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#include <omp.h>#include <unistd.h>#define msec 1000int 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);}

При использовании технологии Intel Cluster OpenMP программист:

Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, вычисляющей число Пи:
#include <mpi.h>#include <omp.h>#define num_steps 100000void 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();}

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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];}

Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#include <omp.h>#include <stdio.h>#define N 100int 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);}

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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];}

Определите значение переменной 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);}

Найдите ошибку в следующем фрагменте программы:
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;          }     }}

При использовании гибридной модели параллельного программирования MPI/OpenMP:

Переменные, которые разделяются нитями, и доступ к которым обрабатывается в технологии Intel Cluster OpenMP механизмом DSM, могут быть заданы при помощи:

Реализация технологии Intel Cluster OpenMP стала возможной, поскольку в OpenMP используется:

Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#define N 100void work(int i);int main () {    #pragma omp parallel    {        #pragma omp for             for (int i=0;i<N;i++) work (i);    }}

Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#define N 100omp_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];    }}

Функция omp_get_num_threads возвращает:

Найдите ошибку в следующем фрагменте программы:
#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 ();     }}

Найдите ошибку в следующем фрагменте программы:
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);}

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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];      }}

Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм.
#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 по завершении выполнения этой программы:

При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (*: prod), где переменная prod имеет тип integer, для каждой нити создается локальная копия переменной prod, начальное значение которой будет инициализировано:

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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);}

Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#include <omp.h>#include <unistd.h>#define msec 1000int 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);}

Пусть перед входом в параллельную область вызывается функция omp_set_num_threads. Пусть в директиве создания этой параллельной области указана клауза num_threads. Количество создаваемых нитей будет:

Найдите ошибку в следующем фрагменте программы:
#define N 10int 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];}

Найдите ошибку в следующем фрагменте программы:
int numt=0;#pragma omp parallel{    #pragma omp critical       {            numt=omp_get_num_threads();           #pragma omp barrier           #pragma omp flush (numt)       }}

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;          }     }}

Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#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);    }}

Найдите ошибку в следующем фрагменте программы:
#include <math.h>double x=1024.0;int n=1024;#pragma omp parallel{    #pragma omp atomic    x=sqrt(x);    #pragma omp atomic    n&=0177;}

Найдите ошибку в следующем фрагменте программы:
#define N 10int i;#pragma omp parallel firstprivate(i) lastprivate(i){    for (i=0; i<N; i++) {         …    }}

Найдите ошибку в следующем фрагменте MPI/OpenMP-программы, вычисляющей число Пи:
#include <mpi.h>#include <omp.h>#define num_steps 100000void 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();}