ІП-05 Гапій ЛР4

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

Міністерство освіти і науки України Національний технічний університет

України «Київський політехнічний інститут імені Ігоря Сікорського»


Факультет інформатики та обчислювальної техніки Кафедра
обчислювальної техніки

Лабораторна робота №4
з дисципліни
«Програмне забезпечення високопродуктивних комп’ютерних систем»

Тема: «Бібліотека OpenMP. Бар’єри, критичні секції»

Виконав: Перевірив:
студент групи ІП-05 Корочкін О. В.
Гапій Денис Едуардович
номер у списку групи: 4

Київ 2023
Мета: Розробка програми для паралельної комп’ютерної системи зі спільною
пам’яттю, мовою C++. Використати бар’єри та критичні секції бібліотеки OpenMP для
організації взаємодії між потоками.

Варіант: 10
Технічне Завдання:
MR = MB*(MC*MM)*d + min(Z)*MC

Введення по потоках:
 1: MB
 2: --
 3: MC
 4: d, MM, Z

Виведення в потоці:
 2: MR

Виконання Роботи
[Етап 1] Розробка паралельного алгоритму:
Обчислення Формула Примітка
1 a_i = min(Zh) i = 1..4
2 a = min(a, a_i) СР: a
3 MRh= MB*(MC * MMh)*d + a * MCh СР: MB, d, a

Спільні ресурси:
a, MB, d, a
[Етап 2] Розроблення алгоритмів роботи кожного процесу:
Задача T1
1 Введення MB
2 Сигнал задачам T2-T4 про введення MB S2-1, S3-1, S4-1
3 Чекати на введення MС в T3 W3-1
4 Чекати на введення d, MM, Z в T4 W4-1
5 Обчислення 1 [a1= min(Zh)]
6 Обчислення 2 [a = min(a, a1)] КД1
7 Сигнал задачам T2-T4 про обчислення a S2-2, S3-2, S4-2
8 Чекати на завершення обчислення a в задачах T2-T4 W2-1, W3-2, W4-2
9 Копіювати MB1 = MB КД2
1 Копіювати d1 = d КД3
0
1 Копіювати a1 = a КД4
1
1 Обчислення 3 [MRh = MB1*(MC * MMh)*d1 + a1 * MCh]
2
1 Сигнал задачі T2 про обчислення MRh S2-3
3
Задача T2
1 Введення MX
2 Сигнал задачам T1, T3, T4 про введення MX S1-1, S3-1, S4-1
3 Чекати на введення MB в T1 W1-1
4 Чекати на введення d, MM, Z в T4 W4-1
5 Обчислення 1 [a2= min(Zh)]
6 Обчислення 2 [a = min(a, a2)] КД1
7 Сигнал задачам T1, T3, T4 про обчислення a S2-2, S3-2, S4-2
8 Чекати на завершення обчислення a в задачах T1, T3, T4 W1-2, W3-1, W4-2
9 Копіювати MB2 = MB КД2
1 Копіювати d2 = d КД3
0
1 Копіювати a2 = a КД4
1
1 Обчислення 3 [MRh = MB2*(MCh * MMh)*d2 + a2 * MCh]
2
1 Чекати на завершення обчислення a в задачах T1, T3, T4 W1-3, W3-2, W4-3
3
1 Виведення MR
4
Задача T3
1 Введення MC
2 Сигнал задачам T1, T2, T4 про введення MC S1-1, S2-1, S4-1
3 Чекати на введення MB в T1 W1-1
4 Чекати на введення d, MM, Z в T4 W4-1
5 Обчислення 1 [a3= min(Zh)]
6 Обчислення 2 [a = min(a, a3)] КД1
7 Сигнал задачам T1, T2, T4 про обчислення a S1-2, S3-2, S4-2
8 Чекати на завершення обчислення a в задачах T1, T2, T4 W1-2, W2-1, W4-2
9 Копіювати MB3 = MB КД2
1 Копіювати d3 = d КД3
0
1 Копіювати a3 = a КД4
1
1 Обчислення 3 [MRh = MB3*(MCh * MMh)*d3 + a3 * MCh]
2
1 Сигнал задачі T2 про обчислення MRh S2-3
3
Задача T4
1 Введення d, MM, Z
2 Сигнал задачам T1, T2, T3 про введення d, MM, Z S1-1, S2-1, S3-1
3 Чекати на введення MB в T1 W1-1
4 Чекати на введення MC в T3 W3-1
5 Обчислення 1 [a4= min(Zh)]
6 Обчислення 2 [a = min(a, a4)] КД1
7 Сигнал задачам T1, T2, T3 про обчислення a S1-2, S2-2, S3-2
8 Чекати на завершення обчислення a в задачах T1, T2, T3 W1-2, W2-1, W3-2
9 Копіювати MB4 = MB КД2
1 Копіювати d4 = d КД3
0
1 Копіювати a4 = a КД4
1
1 Обчислення 3 [MRh = MB4*(MCh * MMh)*d4 + a4 * MCh]
2
1 Сигнал задачі T2 про обчислення MRh S2-3
3
[Етап 3] Розроблення структурної схеми взаємодії задач:

Призначення взаємодії потоків та захисту спільних ресурсів:


CS1 – критична секція для захисту спільної змінної a;
CS2 – критична секція для захисту спільної змінної MB;
CS3 – критична секція для захисту спільної змінної d;
CS4 – критична секція для захисту спільної змінної a;
Бар’єри використано для синхронізації: при введені / по обчисленню / перед
виведенням.
[Етап 4] Розробка програми:
Лістинг App.java
/**
* Паралельне програмування
* Лабораторна робота: №4
* Оцінка: A
* Варіант: 10
* Завдання: MM = MB*(MC*MM)*d + min(Z)*MC
* • ПВВ1 – MB
* • ПВВ2 – MM
* • ПВВ3 – MC
* • ПВВ4 – d, MM, Z
* Виконав: Гапій Денис Едуардович ІП-05
* Дата: 24.04.2023
**/

using namespace std;

#pragma region Includes


#include <iostream>
#include <string>
#include <omp.h>
#include <chrono>
#pragma endregion

#pragma region Constants


const int N = 4;
const int P = 4;
const int H = N / P;
#pragma endregion

#pragma region Functions


int get_scalar() { return 1; }

int* get_vector(int size) {


int* v = new int[size];
for (int i = 0; i < size; ++i)
v[i] = get_scalar();
return v;
}

int** get_matrix(int rows, int cols) {


int** m = new int* [rows];
for (int r = 0; r < rows; ++r)
m[r] = get_vector(cols);
return m;
}

int** copy_matrix(int** matrix, int rows, int cols) {


int** cp = new int* [rows];
for (int r = 0; r < rows; ++r) {
cp[r] = new int[cols];
for (int c = 0; c < cols; ++c)
cp[r][c] = matrix[r][c];
}
return cp;
}

string str(int** matrix, int rows, int cols) {


string s = "[\n";
for (int r = 0; r < rows; ++r) {
s.append(" [ ");
for (int c = 0; c < cols; ++c) {
s.append(" ").append(to_string(matrix[r][c])).append(" ");
}
s.append(" ]\n");
}
s.append("]");
return s;
}
#pragma endregion

int main()
{
cout << "Lab started" << endl;
auto start = chrono::high_resolution_clock::now();
int t;
int d, a = INT_MAX;
int* Z;
int** MR, ** MC, ** MB, ** MM;

int cp_a, cp_d;


int** cp_MB;

int sum, end, startH;


MR = new int* [N];
for (int r = 0; r < N; ++r)
MR[r] = new int[N];

#pragma omp parallel num_threads(P) default(shared) private(t, cp_d, cp_a, cp_MB,


sum, end, startH) //shared(a, d, MB, MR)
{
t = omp_get_thread_num();

#pragma omp critical(debug)


cout << "T" << t + 1 << " started" << endl;

switch (t) {
case 0: // Input MB on T1
MB = get_matrix(N, N);
startH = 0;
break;
case 1:
startH = H;
break;
case 2: // Input MC on T3
MC = get_matrix(N, N);
startH = H*2;
break;
case 3: // Input d, MM, Z on T4
MM = get_matrix(N, N);
Z = get_vector(N);
d = get_scalar();
startH = H*3;
break;
default:
break;
}
end = startH + H;

// INPUT BARRIER
#pragma omp barrier

#pragma omp for reduction(min: a) // CS1


for (int i = 0; i < N; ++i)
if (Z[i] < a) a = Z[i];

// CALCULATION BARRIER
#pragma omp barrier

#pragma omp critical(CS2)


{
cp_a = a;
}

#pragma omp critical(CS3)


{
cp_d = d;
}

#pragma omp critical(CS4)


{
cp_MB = copy_matrix(MB, N, N);
}

for (int i = startH; i < end; ++i) {


#pragma omp for
for (int j = 0; j < N; ++j) {
sum = 0;
for (int k = 0; k < N; ++k)
sum += cp_MB[i][j] * MC[k][j] * MM[i][k];
MR[i][j] = sum * cp_d + cp_a * MC[i][j];
}
}

// PRE OUTPUT BARRIER


#pragma omp barrier

if (t == 1) {
#pragma omp critical(debug)
cout << str(MR, N, N) << endl;
}

for (int i = 0; i < N; ++i) {


delete[] cp_MB[i];
}
delete[] cp_MB;

#pragma omp critical(debug)


cout << "T" << t + 1 << " finished" << endl;
} // pragma omp parallel

for (int i = 0; i < N; ++i) {


delete[] MC[i];
delete[] MB[i];
delete[] MM[i];
delete[] MR[i];
}
delete[] Z;
delete[] MC;
delete[] MB;
delete[] MM;
delete[] MR;

auto stop = chrono::high_resolution_clock::now();


auto duration = chrono::duration_cast<chrono::milliseconds>(stop - start);
cout << "Lab finished in " << duration.count() << " ms" << endl;
}
[Етап 5] Тестування програми:
Результат роботи програми при N=4:

Коефіцієнт прискорення:
N T4 T1 Кп = T1/T4
100 1.7
1600 2.2
3000 3.15
Навантаження ядер для T1:
Навантаження ядер для T1-T4:

Апаратні характеристики можна спостерігати на зображені вище. ОС: Windows. X64

Висновок:
- Виконано розробку паралельного алгоритму задачі, яка потребує використання
паралельних алгоритмів для множення матриць між собою, скаляру на матричну
велечину та пошук мінімального значення у векторі. Визначено перелік спільних
ресурсів, для яких потрібно вирішити завдання взаємного виключення.
- Проведено розробку алгоритмів потоків Т1-Т4 для паралельно розподіленого
обчислення своєї частини результату рівняння. Окрім взаємних виключень та
обчислень, було передбачено синхронізацію для вводу / виводу значень.
- Розроблено схему роботи усіх чотирьох потоків. Визначено два засоби організації
взаємодії потоків, а саме – критичні секції для захисту спільних змінних та бар’єри
для додаткової синхронізації потоків.
- Виконано розробку програми мовою C++ та за допомоги функціоналу бібліотеки
OpenMP. Для створення потоків використано #pragma omp parallel з заданням
кількості потоків через num_threads(P), заданням змінних які існують окремо у
кожному потоці, задопомоги: private(t, cp_d, cp_a, cp_MB, sum) та спільні ресурси
через shared(a, d, MB). Для синхронізації та критичних ділянок було застосовано
методи:
 #pragma omp critical: критичні секції, для почергового звертання до КД.
 #pragma omp barrier: бар’єр для очікування усіх потоків.
 #pragma omp for: Призводить до того, що робота, виконана в for циклі
всередині паралельної області, розподіляється між потоками.
- З тестування можемо винести, що:
 Програмні результати співпали з обчисленнями у онлайн калькуляторі
(WolframApha) (17 17 17 17) * 4.
 При відключені інших ядер, потоки продовжують працювати через T1. І
скомпільований с++ застосунок доводить обчислення до кінця, але за більшу
кількість часу.
 Підраховано коефіцієнт прискорення для N : 100, 1600, 3000. Для аналізу
витраченого часу виділено час початку та закінчення роботи усього застосунку
за допомогою функції бібліотеки `chrono`: chrono::high_resolution_clock::now().

You might also like