Главная / Программирование /
Параллельное программирование с OpenMP / Тест 5
Параллельное программирование с OpenMP - тест 5
Упражнение 1:
Номер 1
Директива master
Ответ:
 (1) определяет блок операторов в программе, который будет выполнен одной нитью группы. Остальные нити группы дожидаются завершения выполнения этого блока
 
 (2) определяет блок операторов в программе, который будет выполнен master
-нитью. Остальные нити группы дожидаются завершения выполнения этого блока
 
 (3) определяет блок операторов в программе, который будет выполнен master
-нитью. Остальные нити группы не дожидаются завершения выполнения этого блока
 
Номер 2
Найдите ошибку в следующем фрагменте программы:
#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];
}
Ответ:
 (1) оператор for
не может быть использован внутри конструкции master
 
 (2) по завершении конструкции master
отсутствует директива barrier
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 3
Найдите ошибку в следующем фрагменте программы:
#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];
}
Ответ:
 (1) оператор for
не может быть использован внутри конструкции master
 
 (2) по завершении конструкции master
отсутствует директива barrier
 
 (3) в данном фрагменте программы ошибки нет
 
Упражнение 2:
Номер 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];
}
Ответ:
 (1) оператор for
не может быть использован внутри конструкции master
 
 (2) оператор, в котором изменяется значение общей переменной B[N-1]
выполняется без какой-либо синхронизации
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 2
Найдите ошибку в следующем фрагменте программы:
#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;
}
Ответ:
 (1) изменение общей переменной B[iam]
выполняется без какой-либо синхронизации
 
 (2) чтение/изменение общей переменной tmp
выполняется без какой-либо синхронизации
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 3
Найдите ошибку в следующем фрагменте программы:
#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;
}
Ответ:
 (1) изменение общей переменной B[iam]
выполняется без какой-либо синхронизации
 
 (2) чтение/изменение переменной tmp
выполняется без какой-либо синхронизации
 
 (3) в данном фрагменте программы ошибки нет
 
Упражнение 3:
Номер 1
Найдите ошибку в следующем фрагменте программы:
#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];
}
}
Ответ:
 (1) чтение общих переменных А[iam]
и B[iam]
в операторах вида A[iam]>0
и B[iam]>0
выполняется без какой-либо синхронизации
 
 (2) изменение общей переменной sum внутри критических секций update_a
и update_b
может выполняться одновременно несколькими нитями, поскольку названия критических секций отличаются
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 2
Найдите ошибку в следующем фрагменте программы:
#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];
}
}
Ответ:
 (1) критические секции, определяемые директивой critical
, не могут быть вложены друг в друга
 
 (2) дедлок - взаимная блокировка нитей, возникающая при входе master
-нитью в критическую секцию с именем update_a
и любой другой нитью в секцию с именем update_b
(в этом случае вложенные критические секции не смогут быть обработаны)
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 3
Найдите ошибку в следующем фрагменте программы:
#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];
}
Ответ:
 (1) критические секции не могут быть вложены друг в друга
 
 (2) одноименные критические секции не могут быть вложены друг в друга
 
 (3) в данном фрагменте программы ошибки нет
 
Упражнение 4:
Номер 1
Найдите ошибку в следующем фрагменте программы:
int numt=0;
#pragma omp parallel
{
#pragma omp master
{
#pragma omp critical
{
numt=omp_get_num_threads();
}
#pragma omp barrier
}
}
Ответ:
 (1) директива barrier
не может быть использована внутри конструкции master
 
 (2) директива critical
не может быть использована внутри конструкции master
;
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 2
Найдите ошибку в следующем фрагменте программы:
int numt=0;
#pragma omp parallel
{
#pragma omp single
{
#pragma omp critical
{
numt=omp_get_num_threads();
}
#pragma omp barrier
}
}
Ответ:
 (1) директива critical
не может быть использована внутри конструкции single
 
 (2) директива barrier
не может быть использована внутри конструкции single
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 3
Найдите ошибку в следующем фрагменте программы:
int numt=0;
#pragma omp parallel
{
#pragma omp critical
{
numt=omp_get_num_threads();
#pragma omp barrier
#pragma omp flush (numt)
}
}
Ответ:
 (1) директива barrier
не может быть использована внутри критической секции (конструкции critical
)
 
 (2) директива flush
не может быть использована внутри критической секции (конструкции critical
)
 
 (3) в данном фрагменте программы ошибки нет
 
Упражнение 5:
Номер 1
Найдите ошибку в следующем фрагменте программы:
#include <math.h>
double x=1024.0;
int n=1024;
#pragma omp parallel
{
#pragma omp atomic
x+=sqrt(x);
#pragma omp atomic
n&=0177;
}
Ответ:
 (1) при вычислении выражения в правой части оператора присваивания, указанного в конструкции atomic, не может быть использована переменная, указанная в левой части оператора присваивания
 
 (2) оператор &
(побитовое И
) не может быть использован в конструкции atomic
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 2
Найдите ошибку в следующем фрагменте программы:
#include <math.h>
double x=1024.0;
int n=1024;
#pragma omp parallel
{
#pragma omp atomic
x=sqrt(x);
#pragma omp atomic
n&=0177;
}
Ответ:
 (1) оператор &
(побитовое И
) не может быть использован в конструкции atomic
 
 (2) оператор вида x=sqrt(x)
не может быть использован в конструкции atomic
 
 (3) в данном фрагменте программы ошибки нет
 
Номер 3
Найдите ошибку в следующем фрагменте программы:
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);
Ответ:
 (1) после установки блокировки в результате вызова функции omp_set_lock(&lcka)
, повторное обращение нитью к функции omp_set_lock(&lckb)
некорректно (повторное обращение omp_set_lock(&lckb)
должно быть заменено на omp_set_nest_lock(&lckb)
)
 
 (2) дедлок - взаимная блокировка нитей, возникающая, в случае если master-нить, выполнила omp_set_lock (&lcka)
, а другая нить выполнила omp_set_lock (&lckb)
 
 (3) в данном фрагменте программы ошибки нет