Отказоустойчивые вычислительные системы. Лабораторная работа №3
Состав работы
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Работа представляет собой rar архив с файлами (распаковать онлайн), которые открываются в программах:
- Microsoft Word
Описание
ЛАБОРАТОРНАЯ №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]=i; B[i]=2*i; C[i]=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[i]=A[i]+B[i];
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.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]=i; B[i]=2*i; C[i]=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[i]=A[i]+B[i];
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
Рецензия
Задорожный Анатолий Филиппович
Оценена Ваша работа по предмету: Отказоустойчивые вычислительные системы (ДВ 3.2)
Вид работы: Лабораторная работа 3
Оценка:Зачет
Дата оценки: 09.05.2019
Рецензия
Задорожный Анатолий Филиппович
Похожие материалы
Отказоустойчивые вычислительные системы
nura
: 15 июня 2019
96. Дан одномерный массив A из n элементов, расположенный в общей памяти. Написать программу определения маскимального и минимального элементов массива A. (Примечание: использование опции reduction директивы parallel).
106. Написать и реализовать параллельную программу перемножения квадратных матриц на 4-х ядерном процессоре. Размерность массивов N = № пароля *100. Использовать OpenMP.
116. Написать программу параллельного решения задачи Дирихле методом Гаусса-Зейделя для 4-х процесcорной ВС.
200 руб.
Лабораторная работа №3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант №4
IT-STUDHELP
: 16 июня 2019
ЛАБОРОТОРНАЯ №3. ПАРАЛЛЕЛЬНЫЕ ЦИКЛЫ В OpenMP
Задание
Цель лабораторной работы – рассмотреть различные условия выполнения параллельных циклов.
Исходные тексты программ
Упражнение 4. Дан одномерный массив A из n элементов, расположенный в общей памяти. Написать программу подсчет суммы элементов массива A. Если n меньше 100, то программа выполняется последовательно только главной нитью. Если n больше 100, то подсчет суммы выполняется всеми нитями. Если n равно 100, то программа аварийно завершает
480 руб.
Отказоустойчивые вычислительные системы. Билет №17
Prorabs
: 29 декабря 2019
1. В каких величинах проводится оценки производительности многопроцессорных вычислительных систем?
4. К какому классу в соответствии с систематикой Флинна относятся векторные и векторно-конвейерные ВС?
8. В качестве системообразующего вычислительного модуля в кластерных системах используется....
9. Два или более ПК, объединяемых по топологии «шина» или с помощью коммутатора и являющиеся единым информационно-вычислительным ресурсом, называют ....
200 руб.
Лабораторная работа 2-3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант 7
IT-STUDHELP
: 14 мая 2022
ЛАБОРОТОРНАЯ №2. СОЗДАНИЕ ПАРАЛЛЕЛЬНЫХ ОБЛАСТЕЙ В OpenMP
Задание
Цель лабораторной работы – рассмотреть условия выполнения параллельных областей. Распределение выполняемой программой работы между главной нитью и остальными.
Исходные тексты программ
Упражнение 4. Напишите программу скалярного произведения двух векторов. При инициализации параллельной области явно укажите количество используемых нитей 2 или 4.
Упражнение 5. Программу упражнения 4 измените так, чтобы вывод результата скалярного
600 руб.
Отказоустойчивые вычислительные системы. Лабораторная работа №2
nura
: 12 мая 2019
ЛАБОРОТОРНАЯ №2. СОЗДАНИЕ ПАРАЛЛЕЛЬНЫХ ОБЛАСТЕЙ В OpenMP.
Цель лабораторной работы – рассмотреть Условия выполнения параллельных областей. Распределение выполняемой программой работы между главно нитью и остальными.
2.1.Обзор директив разделения задач
При запуске программы создается процесс и запускается одна нить приложения OpenMP. Первая нить называется главная, она существует на протяжении всего цикла работы программы, в литературе не редко главная нить называется нить-мастер (master threa
550 руб.
Отказоустойчивые вычислительные системы. Лабораторная работа №1
nura
: 12 мая 2019
ЛАБОРОТОРНАЯ №1. ИЗУЧЕНИЕ РАБОТЫ С НИТЯМИ в OpenMP.
Цель лабораторной работы – знакомство с библиотекой OpenMP и получение первичных навыков параллельного программирования.
1. Создание приложения с применением OpenMP
1. Запустите Microsoft Visual Studio 2010.
2. Выбирите пункт в меню File -> New -> Project, или нажмите Ctrl+Shift+N
3. В окне New Project в раскрывающемся списке Visual C++ выбирите Win32. В подокне Templates установите Win32 Console Application. Введите имя (Name), например, examp
300 руб.
Контрольная и Лабораторная работа 2-3 по дисциплине: Отказоустойчивые вычислительные системы. Вариант 7
IT-STUDHELP
: 14 мая 2022
7. В чем особенность кластерных вычислительных систем?
17. Назовите важнейшие свойства архитектуры ВС.
27. Какое расписание является оптимальным?
37. Как определяется понятие стоимости вычислений?
47. Зависят ли параметрически правила масштабирования от количества процессоров?
57. Какие проблемы возникают при использовании общих данных в
параллельно выполняемых потоках?
67. Как определяются общие и локальные переменные потоков?
77. Как используются постоянные локальные переменные потоков (директ
1300 руб.
Зачет по дисциплине: Отказоустойчивые вычислительные системы. Билет № 2
IT-STUDHELP
: 18 апреля 2021
Билет № 2
2. Критериями оценки эффективности многопроцессорных вычислительных систем являются:
Масштабируемость, Отказоустойчивость, Производительность.
Многопроцессорность, Надежность, Вычислительная мощность.
Надежность, Производительность, Мультипроцессность.
4. К какому классу в соответствии с систематикой Флинна относятся векторные и векторно-конвейерные ВС?
SIMD.
SISD.
MISD.
MIMD.
6. Какие преимущества предоставляет пользователям вычислительных систем с суперкомпьютерным уровнем кластер
400 руб.
Другие работы
ММА/ИДО Иностранный язык в профессиональной сфере (ЛТМ) Тест 20 из 20 баллов 2024 год
mosintacd
: 28 июня 2024
ММА/ИДО Иностранный язык в профессиональной сфере (ЛТМ) Тест 20 из 20 баллов 2024 год
Московская международная академия Институт дистанционного образования Тест оценка ОТЛИЧНО
2024 год
Ответы на 20 вопросов
Результат – 100 баллов
С вопросами вы можете ознакомиться до покупки
ВОПРОСЫ:
1. We have … to an agreement
2. Our senses are … a great role in non-verbal communication
3. Saving time at business communication leads to … results in work
4. Conducting negotiations with foreigners we shoul
150 руб.
Задание №2. Методы управления образовательными учреждениями
studypro
: 13 октября 2016
Практическое задание 2
Задание 1. Опишите по одному примеру использования каждого из методов управления в Вашей профессиональной деятельности.
Задание 2. Приняв на работу нового сотрудника, Вы надеялись на более эффективную работу, но в результате разочарованы, так как он не соответствует одному из важнейших качеств менеджера - самодисциплине. Он не обязателен, не собран, не умеет отказывать и т.д.. Но, тем не менее, он отличный профессионал в своей деятельности. Какими методами управления Вы во
200 руб.
Особенности бюджетного финансирования
Aronitue9
: 24 августа 2012
Содержание:
Введение
Теоретические основы бюджетного финансирования
Понятие и сущность бюджетного финансирования
Характеристика основных форм бюджетного финансирования
Анализ бюджетного финансирования образования
Понятие и источники бюджетного финансирования образования
Проблемы бюджетного финансирования образования
Основные направления совершенствования бюджетного финансирования образования
Заключение
Список использованный литературы
Цель курсовой работы – исследовать особенности бюджетного фин
20 руб.
Программирование (часть 1-я). Зачёт. Билет №2
sibsutisru
: 3 сентября 2021
ЗАЧЕТ по дисциплине “Программирование (часть 1)”
Билет 2
Определить значение переменной y после работы следующего фрагмента программы:
a = 3; b = 2 * a – 10; x = 0; y = 2 * b + a;
if ( b > y ) or ( 2 * b < y + a ) ) then begin x = b – y; y = x + 4 end;
if ( a + b < 0 ) and ( y + x > 2 ) ) then begin x = x + y; y = x – 2 end;
200 руб.