Студопедия — Лабораторна робота №1
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Лабораторна робота №1






Модель даних в OpenMP передбачає наявність як загальної для всіх потоків області пам'яті, так і локальної області пам'яті для кожного потоку. У OpenMP змінні в паралельних областях програми розділяються на два основні класи:

shared (загальні; всі потоки бачать одну і ту ж змінну);

private (локальні, приватні; кожен потік бачить свій екземпляр даної змінної).

Загальна змінна завжди існує лише в одному екземплярі для всієї зони дії і доступна всім потокам під одним і тим же ім'ям. Оголошення локальної змінної викликає породження свого екземпляра даною змінною (того ж типа і розміру) для кожного потоку. Зміна потоком значення своєї локальної змінної ніяк не впливає на зміну значення цій же локальній змінній в інших потоках.

Якщо декілька потоків одночасно записують значення загальної змінної без виконання синхронізації або якщо як мінімум один потік читає значення загальної змінної і як мінімум один потік записує значення цієї змінної без виконання синхронізації, то виникає ситуація так званої «гонки даних» (data race), при якій результат виконання програми непередбачуваний.

За умовчанням, всі змінні, породжені поза паралельною областю, при вході в цю область залишаються загальними (shared). Виняток становлять змінні, що є лічильниками ітерацій в циклі, по очевидних причинах. Змінні, породжені усередині паралельної області, за умовчанням є локальними (private). Явно призначити клас змінних за умовчанням можна за допомогою опції default. Не рекомендується постійно покладатися на правила за умовчанням, для більшої надійності краще завжди явно описувати класи використовуваних змінних, вказуючи в директивах OpenMP опції private, shared, firstprivate, lastprivate, reduction.

Приклад демонструє використання опції private. У даному прикладі змінна n оголошена як локальна змінна в паралельній області. Це означає, що кожен потік працюватиме зі своєю копією змінної n, при цьому на початку паралельної області на кожному потоці змінна n не буде ініціалізована. В ході виконання програми значення змінної n буде виведено в чотирьох різних місцях. Перший раз значення n буде виведено в послідовній області, відразу після привласнення змінній n значення 1. Другий раз всі потоки виведуть значення своєї копії змінною n на початку паралельної області. Далі всі потоки виведуть свій порядковий номер, отриманий за допомогою функції omp_get_thread_num() і привласнений змінній n. Після завершення паралельної області буде ще раз виведено значення змінної n, яке виявиться рівним 1 (не змінилося під час виконання паралельної області).

#include <stdio.h>

#include <omp.h>

int main(int argc, char *argv[])

{

int n=1;

printf("n у послідовній області (початок): %d\n", n);

 

#pragma omp parallel private(n)

{

printf("Значення n на потоці (на вході): %d\n", n);

n=omp_get_thread_num();

printf("Значення n на потоці (на виході): %d\n", n);

}

 

printf("n у послідовній області (кінець): %d\n", n);

}

Приклад демонструє використання опції shared. Масив m оголошений загальним для всіх потоків. На початку послідовної області масив m заповнюється нулями і виводиться на друк. У паралельної області кожен потік знаходить елемент, номер якого збігається з порядковим номером потоку в загальному масиві, і привласнює цьому елементу значення 1. Далі, в послідовній області друкується змінений масив m.

#include <stdio.h>

#include <omp.h>

int main(int argc, char *argv[])

{

int i, m[10];

printf("Масив m на початку:\n");

for (i=0; i<10; i++){

m[i]=0;

printf("%d\n", m[i]);

}

#pragma omp parallel shared(m)

{

m[omp_get_thread_num()]=1;

}

printf("Масив m в кінці:\n");

for (i=0; i<10; i++) printf("%d\n", m[i]);

}

Приклад демонструє використання опції firstprivate. Змінна n оголошена як firstprivate в паралельній області. Значення n буде виведено в чотирьох різних місцях. Перший раз значення n буде виведено в послідовній області відразу після ініціалізації. Другий раз всі потоки виведуть значення своєї копії змінною n на початку паралельної області, і це значення дорівнюватиме 1. Далі, за допомогою функції omp_get_thread_num() всі потоки привласнять змінній n свій порядковий номер і ще раз виведуть значення n. У послідовній області буде ще раз виведено значення n, яке знову виявиться рівним 1.

#include <stdio.h>

#include <omp.h>

int main(int argc, char *argv[])

{

int n=1;

printf("Значення n на початку: %d\n", n);

#pragma omp parallel firstprivate(n)

{

printf("Значення n на потоці (на вході): %d\n", n);

n=omp_get_thread_num();

printf("Значення n на потоці (на виході): %d\n", n);

}

printf("Значення n в кінці: %d\n", n);

}

Директива threadprivate вказує, що змінні із списку мають бути розмножені з тим, щоб кожен потік мав свою локальну копію:

#pragma omp threadprivate( список )

Приклад демонструє використання директиви threadprivate. Глобальна змінна n оголошена як threadprivate змінна. Значення змінної n виводиться в чотирьох різних місцях. Перший раз всі потоки виведуть значення своєї копії змінної n на початку паралельної області, і це значення дорівнюватиме 1 на потоці-майстрові і 0 на інших потоках. Далі за допомогою функції omp_get_thread_num() всі потоки привласнять змінній n свій порядковий номер і виведуть це значення. Потім в послідовній області буде ще раз виведено значення змінної n, яке виявиться рівним порядковому номеру потока-майстра, тобто 0. Востаннє значення змінної n виводиться в новій паралельній області, причому значення кожної локальної копії повинне зберегтися.

#include <stdio.h>

#include <omp.h>

int n;

#pragma omp threadprivate(n)

int main(int argc, char *argv[])

{

int num;

n=1;

#pragma omp parallel private (num)

{

num=omp_get_thread_num();

printf("Значення n на потоці %d (на вході): %d\n", num, n);

n=omp_get_thread_num();

printf("Значення n на потоці %d (на виході): %d\n", num, n);

}

printf("Значення n (середина): %d\n", n);

#pragma omp parallel private (num)

{

num=omp_get_thread_num();

printf("Значення n на потоці %d (ещё раз): %d\n", num, n);

}

}

Якщо необхідно змінну, оголошену як threadprivate, ініціалізувати значенням розмножуваної змінної з потоку-майстра, то на вході в паралельну область можна використати опцію copyin. Якщо значення локальної змінної або змінної, оголошеної як threadprivate, необхідно переслати від одного потоку всім, що працюють в даній паралельній області, для цього можна використовувати опцію copyprivate директиви single.

Приклад демонструє використання опції copyin. Глобальна змінна n визначена як threadprivate. Вживання опції copyin дозволяє ініціалізувати локальні копії змінної n початковим значенням потоку-майстра. Всі потоки виведуть значення n, рівне 1.

#include <stdio.h>

int n;

#pragma omp threadprivate(n)

int main(int argc, char *argv[])

{

n=1;

#pragma omp parallel copyin(n)

{

printf("Значение n: %d\n", n);

}

}


 

Хід роботи

Створити програму яка повинна реалізувати наступні дії:

1.Створити матрицю А розміром m * n, елементи якої заповнюються рандомно, m задає кількість рядків і кількість потоків, які виконуватимуть паралельну область програми, n задає кількість стовпців. Змінні можуть задаватися в програмному коді або вводитися з клавіатури.

2. У паралельній області за допомогою директиви single або master вивести наступні дані: номер лабораторної роботи; назва лабораторної роботи; групу студента; ФІО студента; номер варіанту; завдання.

3.Обробити паралельним способом матрицю відповідно до свого варіанту. Кожен потік повинен обробляти свій рядок матриці. Результати обробки записати в масив В.

4.Вывести результат обробки масиву паралельним способом. При роботі потоку на екран повинна виводитися інформація про номер потоку та номер рядка матриці, яку обробляє потік.

5.Послідовно обробити матрицю відповідно до свого варіанту. Результати обробки записати в масив С.

6.Вывести результат обробки матриці послідовним способом. Визначити час, який був затрачений на обробку паралельним та послідовним способом.

Порівняти отримані результати на наявність ідентичності.

№ Варіанта Завдання
  Знайти мінімальне значення кожного рядка матриці
  Знайти максимальне значення кожного рядка матриці
  Порахувати кількість додатних елементів в кожному рядку матриці
  Порахувати кількість від’ємних елементів в кожному рядку матриці
  Порахувати кількість нульових елементів в кожному рядку матриці
  Порахувати суму елементів в кожному рядку матриці
  Порахувати суму додатних елементів в кожному рядку матриці
  Порахувати суму від’ємних елементів в кожному рядку матриці

 

Контрольні питання

1. У яких випадках може бути необхідне використання опції if директиви parallel?

2. Чим відрізняються директиви single і master?

3. Чи може нитка-майстер виконати область, що асоціюється з директивою single?

4. Чи може нитка з номером 1 виконати область, що асоціюється з директивою master?

5. Чи може одна і та ж змінна виступати в одній частині програми як загальна, а в іншій частині – як локальна?

6. Що станеться, якщо декілька ниток одночасно звернуться до загальної змінної?

7. Чи може статися конфлікт, якщо декілька ниток одночасно звернуться до однієї і тієї ж локальної змінної?

8. Яким чином при вході в паралельну область розіслати всім по народжуваних нитках значення деякої змінної?

9. Чи можна зберегти значення локальних копій загальних змінних після завершення паралельної області?

10. У чому відмінність опції copyin від опції firstprivate?

Лабораторна робота №1







Дата добавления: 2015-09-19; просмотров: 750. Нарушение авторских прав; Мы поможем в написании вашей работы!



Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

Постинъекционные осложнения, оказать необходимую помощь пациенту I.ОСЛОЖНЕНИЕ: Инфильтрат (уплотнение). II.ПРИЗНАКИ ОСЛОЖНЕНИЯ: Уплотнение...

Приготовление дезинфицирующего рабочего раствора хлорамина Задача: рассчитать необходимое количество порошка хлорамина для приготовления 5-ти литров 3% раствора...

Дезинфекция предметов ухода, инструментов однократного и многократного использования   Дезинфекция изделий медицинского назначения проводится с целью уничтожения патогенных и условно-патогенных микроорганизмов - вирусов (в т...

Йодометрия. Характеристика метода Метод йодометрии основан на ОВ-реакциях, связанных с превращением I2 в ионы I- и обратно...

Броматометрия и бромометрия Броматометрический метод основан на окислении вос­становителей броматом калия в кислой среде...

Метод Фольгарда (роданометрия или тиоцианатометрия) Метод Фольгарда основан на применении в качестве осадителя титрованного раствора, содержащего роданид-ионы SCN...

Studopedia.info - Студопедия - 2014-2024 год . (0.011 сек.) русская версия | украинская версия