Автор статьи
Валерия
Эксперт по сдаче вступительных испытаний в ВУЗах
Найдите ошибку в следующем фрагменте программы:
#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; } }}- в данном фрагменте программы ошибки нет
- (Правильный ответ) в директиве for отсутствует клауза private(tmp)
- в директиве for отсутствует клауза private(i)
Определите класс по умолчанию для переменной numt:
int i=0;int numt = omp_get_max_threads();#pragma omp parallel forfor(i=0; i< numt; i++) Work(i);- threadprivate
- private
- (Правильный ответ) shared
Найдите ошибку в следующем фрагменте программы:
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; } }}- перед директивой for отсутствует директива barrier
- в данном фрагменте программы ошибки нет
- (Правильный ответ) в директиве parallel клауза private (a) должна быть заменена на shared(a)
Найдите ошибку в следующем фрагменте программы:
#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;}- чтение/изменение переменной tmp выполняется без какой-либо синхронизации
- изменение общей переменной B[iam] выполняется без какой-либо синхронизации
- (Правильный ответ) в данном фрагменте программы ошибки нет
Способ распределения витков цикла между нитями группы задается при помощи клаузы 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); }}- (Правильный ответ) значение параметра <число итераций> клаузы schedule отличается для каждой нити группы
- в данном фрагменте программы ошибки нет
- при динамическом планировании, задаваемом клаузой schedule(dynamic), параметр <число итераций> задать нельзя
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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); } }}- export OMP_SCHEDULE=”static,15”
- export OMP_SCHEDULE=”static,20”
- (Правильный ответ) export OMP_SCHEDULE=”static,10”
Клауза copyin:
- может быть использована только для переменных, указанных в клаузе private
- (Правильный ответ) может быть использована только для переменных, указанных в директиве threadprivate
- может быть использована как для переменных указанных в директиве threadprivate, так и для переменных, указанных в клаузе private
Определите значение переменной 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);}- 0
- (Правильный ответ) 2
- 1
Директива master
- определяет блок операторов в программе, который будет выполнен одной нитью группы. Остальные нити группы дожидаются завершения выполнения этого блока
- (Правильный ответ) определяет блок операторов в программе, который будет выполнен master-нитью. Остальные нити группы не дожидаются завершения выполнения этого блока
- определяет блок операторов в программе, который будет выполнен master-нитью. Остальные нити группы дожидаются завершения выполнения этого блока
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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); } }}- export OMP_SCHEDULE=”static”
- (Правильный ответ) export OMP_SCHEDULE=”dynamic”
- export OMP_SCHEDULE=”static,10”
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);}- добавить к директиве parallel for клаузу schedule(static,1)
- добавить к директиве parallel for клаузу schedule(dynamic)
- (Правильный ответ) добавить к директиве parallel for клаузу collapse(2)
Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм.
#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 по завершении выполнения этой программы:- 4
- (Правильный ответ) 2
- 1
При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (+: sum), где переменная sum имеет тип integer, для каждой нити создается локальная копия переменной sum, начальное значение которой будет инициализировано:
- MAXINT (максимально возможное целое число)
- -MAXINT (минимально возможное целое число)
- (Правильный ответ) 0
Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#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); }}- управляемый(guided)
- (Правильный ответ) зависит от реализации компилятора
- зависит от значения переменной окружения OMP_SCHEDULE
Найдите ошибку в следующем фрагменте программы:
#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;}- (Правильный ответ) чтение/изменение общей переменной tmp выполняется без какой-либо синхронизации
- в данном фрагменте программы ошибки нет
- изменение общей переменной B[iam] выполняется без какой-либо синхронизации
Процессорная модель консистентности памяти определяется следующим условием:
- все процессы наблюдают операции записи любого процесса в порядке их выполнения. Операции записи различных процессов могут наблюдаться разными процессами в разном порядке
- (Правильный ответ) все процессы наблюдают операции записи любого процесса в порядке их выполнения. Для каждой переменной существует общее согласие относительно порядка, в котором процессы модифицируют эту переменную. Операции записи различных процессов могут наблюдаться разными процессами в разном порядке
- все процессы наблюдают все обращения к ячейкам памяти в одном и том же порядке. Обращения не упорядочены по времени
Найдите ошибку в следующем фрагменте программы:
#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 (); }}- после конструкции single отсутствует директива barrier
- в данном фрагменте программы ошибки нет
- (Правильный ответ) в директиве single отсутствует клауза copyprivate(numt)
Найдите ошибку в следующем фрагменте программы:
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); } }- (Правильный ответ) количество заголовков циклов не соответствуют значению, указанному в клаузе collapse
- в данном фрагменте программы ошибки нет
- в результате использования клаузы default(shared), счетчики циклов — переменные i и j являются общими для всех нитей
Пусть следующая программа скомпилирована компилятором, поддерживающим вложенный параллелизм.
#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 по завершении выполнения этой программы:- 1
- 4
- (Правильный ответ) 2
Найдите ошибку в следующем фрагменте программы:
#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];}- (Правильный ответ) дедлок — взаимная блокировка нитей, возникающая в результате того что одноименные критические секции вложены друг в друга
- в данном фрагменте программы ошибки нет
- критические секции не могут быть вложены друг в друга
Найдите ошибку в следующем фрагменте программы:
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; } }}- в данном фрагменте программы ошибки нет
- в директиве parallel клауза shared(a) должна быть заменена на private(a)
- (Правильный ответ) перед директивой for отсутствует директива barrier
Рассмотрим фрагмент 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) {/*параллельная область*/ … } } Для выполнения параллельной области будет создана группа нитей, состоящая из:
- 2-х нитей
- нескольких нитей (количество создаваемых нитей зависит от переменной окружения OMP_NUM_THREADS)
- (Правильный ответ) 1-ой нити
Найдите ошибку в следующем фрагменте программы:
#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); } }}- используются конструкции распределения работ, которые вложены одна в другую
- (Правильный ответ) клауза shared не может быть использована в директиве for
- в данном фрагменте программы ошибки нет
Функция omp_get_num_threads возвращает:
- максимально возможное количество нитей, которые могут быть использованы при выполнении всей программы
- номер нити в группе
- (Правильный ответ) количество нитей в текущей параллельной области
Параллельная область в OpenMP создается при помощи:
- (Правильный ответ) директивы parallel
- вызова функции omp_set_max_active_levels
- вызова функции omp_set_num_threads
Определите способ распределения витков цикла между нитями для следующего фрагмента программы:
#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); }}- (Правильный ответ) зависит от реализации компилятора
- зависит от значения переменной окружения OMP_SCHEDULE
- динамический (dynamic)
Найдите ошибку в следующем фрагменте программы:
#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; } }}- (Правильный ответ) в директиве for отсутствует клауза private(tmp)
- в данном фрагменте программы ошибки нет
- в директиве parallel отсутствует клауза shared(a)
Использование оператора exit в структурном блоке OpenMP:
- возможно в некоторых OpenMP-компиляторах (зависит от реализации)
- запрещено в стандарте
- (Правильный ответ) разрешено в стандарте
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);}- для первого цикла, выполнение витков которого распределяется между нитями при помощи директивы for, добавить клаузу schedule(dynamic)
- для второго цикла, выполнение витков которого распределяется между нитями при помощи директивы for, добавить клаузу schedule(dynamic)
- (Правильный ответ) объединить две подряд стоящие параллельные области в одну
Найдите ошибку в следующем фрагменте программы:
#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];}- оператор for не может быть использован внутри конструкции master
- (Правильный ответ) по завершении конструкции master отсутствует директива barrier
- в данном фрагменте программы ошибки нет
При реализации компилятором редукционного оператора, описанного при помощи клаузы reduction (*: prod), где переменная prod имеет тип integer, для каждой нити создается локальная копия переменной prod, начальное значение которой будет инициализировано:
- (Правильный ответ) 1
- MAXINT (максимально возможное целое число)
- 0
О сайте
Поделитесь в соцсетях: