Страницу Назад
Поискать другие аналоги этой работы

550

Отказоустойчивые вычислительные системы. Лабораторная работа №3

ID: 200421
Дата закачки: 12 Мая 2019
Продавец: nura (Напишите, если есть вопросы)
    Посмотреть другие работы этого продавца

Тип работы: Работа Лабораторная

Описание:
ЛАБОРАТОРНАЯ №3. ПАРАЛЛЕЛЬНЫЕ ЦИКЛЫ В OpenMP

3.1.Опции директивы parallel
Директива parallel – инициализирует параллельную область и создает группу из OMP_NUM_THREADS нитей. Определение и задание переменной OMP_NUM_THREADS будет дано в следующем параграфе.

Синтаксис оператора. Язык Си
#pragma omp parallel [опция[[,] опция]...]


Возможные опции:
­ if(условие) – выполнение параллельной области по условию. Вхождение в параллельную область осуществляется только при выполнении некоторого условия. Если условие не выполнено, то директива не срабатывает и продолжается обработка программы в прежнем режиме;
­ num_threads (целочисленное выражение) – явное задание количества нитей, которые будут выполнять параллельную область; по умолчанию выбирается последнее значение, установленное с помощью функции omp_set_num_threads(), или значение переменной OMP_NUM_THREADS;
­ reduction(оператор:список) – задаёт оператор и список общих переменных; для каждой переменной создаются локальные копии в каждой нити; локальные копии инициализируются соответственно типу оператора (для аддитивных операций – 0 или его аналоги, для мультипликативных операций – 1 или её аналоги); над локальными копиями переменных после выполнения всех операторов параллельной области выполняется заданный оператор; оператор это: для языка Си – +, *, -, &, |, ^, &&, ||, для языка Фортран – +, *, -, .and., .or., .eqv., .neqv., max, min, iand, ior, ieor; порядок выполнения операторов не определён, поэтому результат может отличаться от запуска к запуску.

Опции, описанные в предыдущей лабораторной:
­ default(private|firstprivate|shared|none);
­ private(список);
­ firstprivate(список);
­ shared(список);
­ copyin(список).

При входе в параллельную область порождаются новые OMP_NUM_THREADS-1 нитей, каждая нить получает свой уникальный номер, причём порождающая нить получает номер 0 и становится основной нитью группы («мастером»).
Остальные нити получают в качестве номера целые числа с 1 до OMP_NUM_THREADS-1. Количество нитей, выполняющих данную параллельную область, остаётся неизменным до момента выхода из области. При выходе из параллельной области производится неявная синхронизация и уничтожаются все нити, кроме породившей.
Все порождённые нити исполняют один и тот же код, соответствующий параллельной области. Предполагается, что в SMP-системе нити будут распределены по различным процессорам (однако это, как правило, находится в ведении операционной системы).
Пример 1 демонстрирует применение опции reduction. В данном примере производится подсчет общего количества порождённых нитей. Каждая нить инициализирует локальную копию переменной count значением 0. Далее, каждая нить увеличивает значение собственной копии переменной count на единицу и выводит полученное число. На выходе из параллельной области происходит суммирование значений переменных count по всем нитям, и полученная величина становится новым значением переменной count в последовательной области.

Пример 1.
Опция reduction на языке Си
#include <stdio.h>
int main(int argc, char *argv[])
{
int count = 0;
#pragma omp parallel num_threads(3)reduction (+: count)
{
count++;
printf("Текущее значение count: %d\\n", count);
}
printf("Число нитей: %d\\n", count);
}

3.2. Параллельные циклы
Если в параллельной области встретился оператор цикла, то, согласно общему правилу, он будет выполнен всеми нитями текущей группы, то есть каждая нить выполнит все итерации данного цикла. Для распределения итераций цикла между различными нитями можно использовать директиву for (do ... [end do]).

Синтаксис оператора. Язык Си
#pragma omp for [опция[[,] опция]...]

Эта директива относится к идущему следом за данной директивой блоку, включающему операторы for (do).
Возможные опции:
­ private(список) – задаёт список переменных, для которых порождается локальная копия в каждой нити; начальное значение локальных копий переменных из списка не определено;
­ firstprivate(список) – задаёт список переменных, для которых порождается локальная копия в каждой нити; локальные копии переменных инициализируются значениями этих переменных в нити-мастере;
­ lastprivate(список) – переменным, перечисленным в списке, присваивается результат с последнего витка цикла;
­ reduction(оператор:список) – задаёт оператор и список общих переменных; для каждой переменной создаются локальные копии в каждой нити; локальные копии инициализируются соответственно типу оператора (для аддитивных операций – 0 или его аналоги, для мультипликативных операций – 1 или её аналоги); над локальными копиями переменных после завершения всех итераций цикла выполняется заданный оператор; оператор это: для языка Си – +, *, -, &, |, ^, &&, ||, для языка Фортран – +, *, -, .and., .or., .eqv., .neqv., max, min, iand, ior, ieor; порядок выполнения операторов не определён, поэтому результат может отличаться от запуска к запуску;
­ schedule(type[, chunk]) – опция задаёт, каким образом итерации цикла распределяются между нитями;
­ collapse(n) — опция указывает, что n последовательных тесновложенных циклов ассоциируется с данной директивой; для циклов образуется общее пространство итераций, которое делится между нитями; если опция collapse не задана, то директива относится только к одному непосредственно следующему за ней циклу;
­ ordered – опция, говорящая о том, что в цикле могут встречаться директивы ordered; в этом случае определяется блок внутри тела цикла, который должен выполняться в том порядке, в котором итерации идут в последовательном цикле;
­ nowait – в конце параллельного цикла происходит неявная барьерная синхронизация параллельно работающих нитей: их дальнейшее выполнение происходит только тогда, когда все они достигнут данной точки; если в подобной задержке нет необходимости, опция nowait позволяет нитям, уже дошедшим до конца цикла, продолжить выполнение без синхронизации с остальными. Если директива end do в явном виде не указана, то в конце параллельного цикла синхронизация все равно будет выполнена.
Если в программе на языке Фортран не указывается директива end do, то она предполагается в конце цикла do.
На вид параллельных циклов накладываются достаточно жёсткие ограничения. В частности, предполагается, что корректная программа не должна зависеть от того, какая именно нить какую итерацию параллельного цикла выполнит. Нельзя использовать побочный выход из параллельного цикла. Размер блока итераций, указанный в опции schedule, не должен изменяться в рамках цикла.

Формат параллельных циклов на языке Си
for([целочисленный тип] i = инвариант цикла;
i {<,>,=,<=,>=} инвариант цикла;
i {+,-}= инвариант цикла)

Эти требования введены для того, чтобы OpenMP мог при входе в цикл точно определить число итераций.
Если директива параллельного выполнения стоит перед гнездом циклов, завершающихся одним оператором, то директива действует только на самый внешний цикл.
Итеративная переменная распределяемого цикла по смыслу должна быть локальной, поэтому в случае, если она специфицирована общей, то она неявно делается локальной при входе в цикл. После завершения цикла значение итеративной переменной цикла не определено, если она не указана в опции lastprivate.
Пример 2 демонстрирует использование директивы for. В последовательной области инициализируются три исходных массива A, B, C. В параллельной области данные массивы объявлены общими. Вспомогательные переменные i и n объявлены локальными. Каждая нить присвоит переменной n свой порядковый номер. Далее с помощью директивы for определяется цикл, итерации которого будут распределены между существующими нитями. На каждой i-ой итерации данный цикл сложит i-ые элементы массивов A и B и результат запишет в i-ый элемент массива C. Также на каждой итерации будет напечатан номер нити, выполнившей данную итерацию.

Пример 2.
Директива for на языке Си.
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[])
{
int A[10], B[10], C[10], i, n;
/* Заполним исходные массивы */
for (i=0; i<10; i++){ A=i; B=2*i; C=0; }
#pragma omp parallel shared(A, B, C) private(i, n)
{
/* Получим номер текущей нити */
n=omp_get_thread_num();
#pragma omp for
for (i=0; i<10; i++)
{
C=A+B;
printf("Нить %d сложила элементы с номером %d\\n",
n, i);
}
}
}

Параллельные секции
Директива sections (sections ... end sections) используется для задания конечного (неитеративного) параллелизма.

Синтаксис оператора. Язык Си
#pragma omp sections [опция[[,] опция]...]


Эта директива определяет набор независимых секций кода, каждая из которых выполняется своей нитью.
Возможные опции:
­ private(список) – задаёт список переменных, для которых порождается локальная копия в каждой нити; начальное значение локальных копий переменных из списка не определено;
­ firstprivate(список) – задаёт список переменных, для которых порождается локальная копия в каждой нити; локальные копии переменных инициализируются значениями этих переменных в нити-мастере;
­ lastprivate(список) – переменным, перечисленным в списке, присваивается результат с последнего витка цикла;
­ reduction(оператор:список) – задаёт оператор и список общих переменных; для каждой переменной создаются локальные копии в каждой нити; локальные копии инициализируются соответственно типу оператора (для аддитивных операций – 0 или его аналоги, для мультипликативных операций – 1 или её аналоги); над локальными копиями переменных после завершения всех итераций цикла выполняется заданный оператор; оператор это: для языка Си – +, *, -, &, |, ^, &&, ||; порядок выполнения операторов не определён, поэтому результат может отличаться от запуска к запуску;
­ nowait – в конце параллельного цикла происходит неявная барьерная синхронизация параллельно работающих нитей: их дальнейшее выполнение происходит только тогда, когда все они достигнут данной точки; если в подобной задержке нет необходимости, опция nowait позволяет нитям, уже дошедшим до конца цикла, продолжить выполнение без синхронизации с остальными. Если директива end do в явном виде не указана, то в конце параллельного цикла синхронизация все равно будет выполнена.

Директива section задаёт участок кода внутри секции sections для выполнения одной нитью.

Синтаксис оператора. Язык Си
#pragma omp section



Перед первым участком кода в блоке sections директива section не обязательна. Какие именно нити будут задействованы для выполнения какой секции, не специфицируется. Если количество нитей больше количества секций, то часть нитей для выполнения данного блока секций не будет задействована. Если количество нитей меньше количества секций, то некоторым (или всем) нитям достанется более одной секции.
Пример 5 иллюстрирует применение директивы sections. Cначала три нити, на которые распределились три секции section, выведут сообщение со своим номером, а потом все нити напечатают одинаковое сообщение со своим номером.

Пример 5.
Директива sections на языке Си.
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[])
{
int n;
#pragma omp parallel private(n)
{
n=omp_get_thread_num();
#pragma omp sections
{
#pragma omp section
{
printf("Первая секция, процесс %d\\n", n);
}
#pragma omp section
{
printf("Вторая секция, процесс %d\\n", n);
}
#pragma omp section
{
printf("Третья секция, процесс %d\\n", n);
}
}
printf("Параллельная область, процесс %d\\n", n);
}
}

Пример 6 демонстрирует использование опции lastprivate. В данном примере опция lastprivate используется вместе с директивой sections. Переменная n объявлена как lastprivate переменная. Три нити, выполняющие секции section, присваивают своей локальной копии n разные значения. По выходе из области sections значение n из последней секции присваивается локальным копиям во всех нитях, поэтому все нити напечатают число 3. Это же значение сохранится для переменной n и в последовательной области.

Пример 6.
Директива lastprivate на языке Си.
#include <stdio.h>
#include <omp.h>
int main(int argc, char *argv[])
{
int n=0;
#pragma omp parallel num_threads(4)
{
#pragma omp sections lastprivate(n)
{
#pragma omp section
{
n=1;
}
#pragma omp section
{
n=2;
}
#pragma omp section
{
n=3;
}
}
printf("Значение n на нити %d: %d\\n",
omp_get_thread_num(), n);
}
printf("Значение n в последовательной области: %d\\n", n);
}




Упражнения

1. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу подсчет суммы элементов массива A. (Примечание: использование опции reduction директивы parallel).
2. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу определения маскимального и минимального элементов массива A. (Примечание: использование опции reduction директивы parallel).
3. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу, в которой нити с четными номерами выводят на экран четные элементы массива A, а нити с нечетными номерами выводят на экран нечетные элементы массива A. (Примечание: использование опции if директивы parallel).
4. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу подсчет суммы элементов массива A. Если n меньше 100, то программа выполняется последовательно только главной нитью. Если n больше 100, то подсчет суммы выполняется всеми нитями. Если n равно 100, то программа аварийно завершается. (Примечание: использование опций if, reduction директивы parallel).
5. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу подсчет суммы элементов массива A, количество нитей задается опцией num_threads. (Примечание: использование опций num_threads, reduction директивы parallel).
6. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу подсчета количества нулевых элементов массива A. (Примечание: использование опции reduction директив parallel, for (do)).
7. Даны два одномерных массива A и B из n элементов, рассположеных в общей памяти. Элементы массива A задаются по следующей формуле a(i)=i, где i – индекс цикла, а элементы массива B по формуле b(i)=thread_num, где thread_num – номер нити. Опцией schedule директивы for (do) задается следующие типы разбиений: static, dynamic, guided. Размер блока chunk равен 1, 2, 4, 8. Программа заполняет массивы A и B, замеряет время выполнения цикла, выводит массивы A, B и время на экран (в файл). Требуется провести анализ времени выполнения программы, определить эффективный тип разбиения массива. (Примечание: количество элементов n более 100, использование опции schedule директив parallel, for (do)).
8. Даны два двумерных массива A и B из NxN элементов, рассположеных в общей памяти. Дано программа запускается на двух нитях. Написать программу заполнения массивов A и B, при условии, что первых массив заполняет первая нить, второй – вторая нить. (Примечание: использование директивы sections).
9. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Элементы массива A задаются по следующей формуле a(i)=i, где i – индекс цикла. Написать программу вывода массива A на экран (в файл) при условии, что вывод выполняется в параллельной области, данные выводятся только один раз. (Примечание: использование директивы single).
10. Дан одномерный массив A из n элементов, рассположеный в общей памяти. Написать программу подсчет суммы элементов массива A. (Примечание: использование комбинированной директивы parallel for(do)).

Вопросы (увеличить количество)

1. В каких случаях может быть необходимо использование опции if директивы parallel?
2. В каких случаях может быть необходимо использование директивs single?
3. Может ли нить-мастер выполнить область, ассоциированную с директивой single?
4. Определите, сколько процессоров доступно в вашей системе для выполнения параллельной части программы, и займите каждый из доступных процессоров выполнением одной нити в рамках общей параллельной области?
5. При помощи трёх уровней вложенных параллельных областей породите 8 нитей (на каждом уровне параллельную область должны исполнять 2 нити). Посмотрите, как будет исполняться программа, если запретить вложенные параллельные области?




Комментарии: Уважаемый студент, дистанционного обучения,
Оценена Ваша работа по предмету: Отказоустойчивые вычислительные системы (ДВ 3.2)
Вид работы: Лабораторная работа 3
Оценка:Зачет
Дата оценки: 09.05.2019
Рецензия

Задорожный Анатолий Филиппович

Размер файла: 567,7 Кбайт
Фаил: Упакованные файлы (.rar)
-------------------
Обратите внимание, что преподаватели часто переставляют варианты и меняют исходные данные!
Если вы хотите, чтобы работа точно соответствовала, смотрите исходные данные. Если их нет, обратитесь к продавцу или к нам в тех. поддержку.
Имейте ввиду, что согласно гарантии возврата средств, мы не возвращаем деньги если вариант окажется не тот.
-------------------

   Скачать

   Добавить в корзину


    Скачано: 8         Коментариев: 0


Есть вопросы? Посмотри часто задаваемые вопросы и ответы на них.
Опять не то? Мы можем помочь сделать!

Некоторые похожие работы:

Лабораторные работы №1,2,3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант №1
Лабораторная работа №1 по дисциплине: Отказоустойчивые вычислительные системы. Для всех вариантов
Контрольная и лабораторные работы №1,2,3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант №4
Лабораторная работа №3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант №4
Контрольная и Лабораторная работа 2-3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант 7
Лабораторная работа №2 по дисциплине: Отказоустойчивые вычислительные системы. Вариант №4
Лабораторная работа 2-3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант 7
Ещё искать по базе с такими же ключевыми словами.

Не можешь найти то что нужно? Мы можем помочь сделать! 

От 350 руб. за реферат, низкие цены. Просто заполни форму и всё.

Спеши, предложение ограничено !



Что бы написать комментарий, вам надо войти в аккаунт, либо зарегистрироваться.

Страницу Назад

  Cодержание / Вычислительные машины, системы и сети / Отказоустойчивые вычислительные системы. Лабораторная работа №3
Вход в аккаунт:
Войти

Забыли ваш пароль?

Вы еще не зарегистрированы?

Создать новый Аккаунт


Способы оплаты:
UnionPay СБР Ю-Money qiwi Payeer Крипто-валюты Крипто-валюты


И еще более 50 способов оплаты...
Гарантии возврата денег

Как скачать и покупать?

Как скачивать и покупать в картинках


Сайт помощи студентам, без посредников!