Главная / Программирование /
Параллельное программирование с OpenMP / Тест 8
Параллельное программирование с OpenMP - тест 8
Упражнение 1:
Номер 1
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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);
}
}
}
Ответ:
 (1) export OMP_SCHEDULE=”static”
 
 (2) export OMP_SCHEDULE=”static,10”
 
 (3) export OMP_SCHEDULE=”dynamic”
 
Номер 2
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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);
}
}
}
Ответ:
 (1) export OMP_SCHEDULE=”static”
 
 (2) export OMP_SCHEDULE=”static,10”
 
 (3) export OMP_SCHEDULE=”dynamic”
 
Номер 3
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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);
}
}
}
Ответ:
 (1) export OMP_SCHEDULE=”static”
 
 (2) export OMP_SCHEDULE=”dynamic”
 
 (3) export OMP_SCHEDULE=”guided”
 
Упражнение 2:
Номер 1
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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);
}
}
}
Ответ:
 (1) export OMP_SCHEDULE=”static,10”
 
 (2) export OMP_SCHEDULE=”static,15”
 
 (3) export OMP_SCHEDULE=”static,20”
 
Номер 2
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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);
}
}
}
Ответ:
 (1) export OMP_SCHEDULE=”static,10”
 
 (2) export OMP_SCHEDULE=”dynamic,15”
 
 (3) export OMP_SCHEDULE=”static,20”
 
Номер 3
Выберите наилучшую стратегию распределения витков цикла между нитями, которая для следующего фрагмента программы даст минимальное время выполнения:
#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);
}
}
}
Ответ:
 (1) export OMP_SCHEDULE=”static,10”
 
 (2) export OMP_SCHEDULE=”dynamic,15”
 
 (3) export OMP_SCHEDULE=”static,20”
 
Упражнение 3:
Номер 1
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
Ответ:
 (1) заменить директиву critical
на директиву atomic 
 (2) заменить директиву critical
на директиву critical (<имя_критической_секции>)
 
 (3) добавить к директиве for клаузу reduction(+:sum)
и убрать директиву critical
 
Номер 2
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
Ответ:
 (1) заменить директиву critical
на директиву critical (<имя_критической_секции>)
 
 (2) заменить директиву critical
на директиву atomic 
 (3) добавить к директиве for
клаузу reduction(^:val)
и убрать директиву critical
 
Номер 3
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
Ответ:
 (1) вместо директивы critical
использовать механизм семафоров (omp_set_lock/omp_unset_lock
) 
 (2) заменить директиву critical
на директиву critical (<имя_критической_секции>)
 
 (3) добавить к директиве for
клаузу reduction(&&:val)
и убрать директиву critical
 
Упражнение 4:
Номер 1
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
}
}
Ответ:
 (1) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу schedule(static,10)
 
 (2) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу nowait
 
 (3) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу schedule(dynamic)
 
Номер 2
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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];
}
}
Ответ:
 (1) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу schedule(static,25)
 
 (2) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу schedule(dynamic)
 
 (3) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу nowait
 
Номер 3
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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];
}
}
Ответ:
 (1) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу schedule(static,10)
 
 (2) для циклов, выполнение витков которых распределяется между нитями при помощи директивы for
, добавить клаузу schedule(dynamic)
 
 (3) для первого цикла, выполнение витков которого распределяется между нитями при помощи директивы for
, добавить клаузу nowait
 
Упражнение 5:
Номер 1
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
Ответ:
 (1) для первого цикла, выполнение витков которого распределяется между нитями при помощи директивы for
, добавить клаузу schedule(dynamic)
 
 (2) для второго цикла, выполнение витков которого распределяется между нитями при помощи директивы for
, добавить клаузу schedule(dynamic)
 
 (3) объединить две подряд стоящие параллельные области в одну 
Номер 2
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
Ответ:
 (1) добавить к директиве parallel for
клаузу schedule(static,1)
 
 (2) добавить к директиве parallel for
клаузу schedule(dynamic)
 
 (3) добавить к директиве parallel for
клаузу collapse(2)
 
Номер 3
Выберите наиболее походящую оптимизацию, которая позволит сократить время выполнения следующего фрагмента программы:
#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);
}
Ответ:
 (1) добавить к директиве parallel for
клаузу schedule(dynamic)
 
 (2) добавить к директиве parallel for
клаузу schedule(static,10)
 
 (3) переставить директиву parallel for
(распределить между нитями выполнение витков цикла по i
)