Главная / Программирование /
Параллельное программирование с OpenMP / Тест 9
Параллельное программирование с OpenMP - тест 9
Упражнение 1:
Номер 1
Директива SHARABLE
в технологии Intel Cluster OpenMP:
Ответ:
 (1) определяет разделяемые нитями переменные, доступ к которым возможен только на одном из узлов кластера 
 (2) определяет разделяемые нитями переменные, доступ к которым обрабатывается механизмом DSM 
 (3) задает, какие переменные, на какой узел кластера необходимо отобразить 
Номер 2
Для выделения памяти для SHARABLE
-переменных в технологии Intel Cluster OpenMP требуется использовать:
Ответ:
 (1) обычные функции malloc
, realloc
и т.д 
 (2) специальные функции kmp_sharable_malloc
, kmp_sharable_realloc
и т.д 
 (3) как обычные, так и специальные функции. Доступ к переменным, для которых память выделена при помощи специальных функций осуществляется быстрее 
Номер 3
Переменные, которые разделяются нитями, и доступ к которым обрабатывается в технологии Intel Cluster OpenMP механизмом DSM, могут быть заданы при помощи:
Ответ:
 (1) клаузы SHARED
 
 (2) директивы SHARABLE
 
 (3) опции компилятора 
Упражнение 2:
Номер 1
Использование технологии Intel Cluster OpenMP целесообразно:
Ответ:
 (1) для OpenMP-программ, с хорошей локализацией данных и требующих малой синхронизации 
 (2) для OpenMP-программ с нерегулярными вычислениями, проводимыми над общими данными 
 (3) для любых OpenMP-программ 
Номер 2
При использовании технологии Intel Cluster OpenMP программист:
Ответ:
 (1) при помощи соответствующих директив распределяет по узлам кластера разделяемые нитями переменные и вычисления, проводимые над этими переменными 
 (2) при помощи соответствующих директив определяет разделяемые нитями переменные, доступ к которым обрабатывается механизмом DSM. Вычисления распределяются по узлам кластера компилятором 
 (3) при помощи соответствующих директив распределяет вычисления по узлам кластера. Данные по узлам кластера распределяются в соответствии с распределением вычислений 
Номер 3
Реализация технологии Intel Cluster OpenMP стала возможной, поскольку в OpenMP используется:
Ответ:
 (1) последовательная модель консистентности памяти (все нити наблюдают все обращения к ячейкам памяти в одном и том же порядке. Обращения не упорядочены по времени) 
 (2) причинная модель консистентности памяти (все нити наблюдают все обращения к ячейкам памяти, связанные причинно-следственной связью в одном и том же порядке) 
 (3) слабая модель консистентности памяти (совместно используемые данные становятся консистентными после операции синхронизации) 
Упражнение 3:
Номер 1
Технология OpenMP по сравнению с MPI имеет следующие преимущества (отметьте все подходящие варианты):
Ответ:
 (1) возможность инкрементального распараллеливания 
 (2) ликвидация дублирования данных в памяти (массивов констант, теневых граней и т.п.) 
 (3) упрощение программирования и эффективность на нерегулярных вычислениях, проводимых над общими данными 
Номер 2
При использовании гибридной модели параллельного программирования MPI/OpenMP:
Ответ:
 (1) все нити взаимодействуют друг с другом только через обмены сообщений 
 (2) все нити, выполняемые на узле кластера, взаимодействуют через общую память, а MPI используется для обмена информацией между узлами кластера 
 (3) все нити, выполняемые на различных узлах кластера, взаимодействуют друг с другом через общую память 
Номер 3
При использовании гибридной модели параллельного программирования DVM/OpenMP:
Ответ:
 (1) все нити, выполняемые на различных узлах кластера, взаимодействуют друг с другом через общую память 
 (2) все нити, выполняемые на узле кластера, взаимодействуют через общую память, а для обмена информацией между узлами кластера используются механизмы, предоставляемые DVM-системой 
 (3) все нити взаимодействуют друг с другом при помощи механизмов, предоставляемых DVM-системой 
Упражнение 4:
Номер 1
Найдите ошибку в следующем фрагменте 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();
}
Ответ:
 (1) все обращения к MPI-функциям в параллельной области должны выполняться одной нитью (например, внутри конструкции single
) 
 (2) переменные numprocs
, myid
, mysteps
должны быть объявлены как private(numprocs, myid, mysteps)
 
 (3) в данном фрагменте программы ошибки нет 
Номер 2
Найдите ошибку в следующем фрагменте 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();
}
Ответ:
 (1) функции MPI_Init
, MPI_Comm_Rank
, MPI_Comm_Size
должны вызываться из параллельной области 
 (2) до завершения выполнения редукционного OpenMP-оператора выполняется вызов функции MPI_Reduce
 
 (3) в данном фрагменте программы ошибки нет 
Номер 3
Найдите ошибку в следующем фрагменте 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();
}
Ответ:
 (1) функции MPI_Init
, MPI_Comm_Rank
, MPI_Comm_Size
и MPI_Reduce
должны вызываться из параллельной области 
 (2) конфликт доступа к данным (race condition
), возникающий в результате выполнения оператора sum *= step
в параллельной области 
 (3) в данном фрагменте программы ошибки нет 
Упражнение 5:
Номер 1
Найдите ошибку в следующем фрагменте 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;
}
Ответ:
 (1) не определен класс для переменных u, w, my_rows, diff
, используемых в параллельной области -shared(u,w,my_rows,diff)
 
 (2) конфликт доступа к данным (race condition
), возникающий в результате выполнения оператора if (tdiff > diff) diff=tdiff
в параллельной области без какой-либо синхронизации 
 (3) в данном фрагменте программы ошибки нет 
Номер 2
Найдите ошибку в следующем фрагменте 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;
}
Ответ:
 (1) не определен класс для переменных u, w, my_rows, diff, global_diff
, используемых в параллельной области -shared(u,w,my_rows,diff,global_diff)
 
 (2) обращения к функции MPI_Allreduce
в параллельной области должны выполняться одной нитью (например, внутри конструкции single
) 
 (3) в данном фрагменте программы ошибки нет 
Номер 3
Найдите ошибку в следующем фрагменте 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;
}
Ответ:
 (1) не определен класс для переменных my_rows, diff, id, p, status, u, w, it, global_diff
, используемых в параллельной области -shared(my_rows,diff,diff,id,p,status,u,w,it,global_diff) 
 (2) отсутствует барьерная синхронизация нитей (директива barrier
) по завершении конструкции master
 
 (3) в данном фрагменте программы ошибки нет