You are on page 1of 6

Колєснік Д. М. КІ – 20, В.

10
ЛАБОРАТОРНА РОБОТА №3
Тема: засоби синхронізації потоків на основі повідомлень в C#.
Мета: виконати паралельні обчислення з використанням декількох
потоків та засобів синхронізації на основі повідомлень.
Завдання №1
Написати паралельну програму, яка обчислює значення виразу F за
варіантом. Кожна арифметична операція має бути виконана в окремому
потоці. Змінні ініціалізуються в тому ж потоці, в якому вони вперше
використовуються. Ініціалізувати змінні наступними значеннями: х1 = 1,
х2 = 2, х3 = 3, х4 = 4, х5 = 5, х6 = 6.

Написати паралельну програму на мові С++, яка обчислює значення виразу


F=(x1+x2)*(x3+x4+x5+x6) . Кожна арифметична операція має бути виконана в
окремому
потоці. Змінні ініціалізуються в тому ж потоці, в якому вони вперше
використовуються. Ініціалізувати змінні наступними значеннями: х1 = 1,
х2 = 2, х3 = 3, х4 = 4, х5 = 5, х6 = 6.
Код програми:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex m1, m2, m3;
int x1, x2, x3, x4, x5, x6;
int res1, res2, res3;

void task1() {
m1.lock();
x1 = 1;
Колєснік Д. М. КІ – 20, В.10
x2 = 2;
res1 = x1 + x2;
m1.unlock();
}
void task2() {
m2.lock();
x3 = 3;
x4 = 4;
x5 = 5;
x6 = 6;
res2 = x3 + x4 + x5 + x6;
m2.unlock();
}
void task3() {
m3.lock();
int f = res1 * res2;
cout << "F = " << f << endl;
m3.unlock();
}
int main() {
thread t1(task1);
thread t2(task2);
t1.join();
t2.join();
thread t3(task3);
t3.join();
return 0;
}
Експеримент:
Колєснік Д. М. КІ – 20, В.10

Завдання №2
Написати паралельну програму, яка обчислює матричний вираз за
варіантом. Всі матриці є квадратними, мають розмірність N і задаються
випадковими цілими числами у діапазоні [–10; 10]. Програма повинна
вирішувати такі завдання:
1) Кількість робочих потоків P, якими виконують паралельні обчислення, має
задаватися користувачем;
2) Потрібно побудувати графік залежності часу виконання програми від
розмірності матриць (N = 103, 104, 105 ...) при однопоточному режимі та
кількості потоків, яка відповідає кількості логічних ядер персонального
комп’ютера.

Написати паралельну програму на мові С++, яка обчислює матричний вираз


(M1+M2*M3+M4+M5)*M6 і виводить результат на екран. Всі матриці є
квадратними, мають розмірність N і задаються випадковими цілими числами
у діапазоні [–10; 10]. Програма повинна вирішувати такі завдання:
1) Кількість робочих потоків P, якими виконують паралельні обчислення, має
задаватися користувачем;
Код програми:
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <random>
using namespace std;
const int N = 1000;
Колєснік Д. М. КІ – 20, В.10
void generate_matrix(vector<vector<int>>& matrix) {
matrix.resize(N);
for (int i = 0; i < N; i++) {
matrix[i].resize(N);
for (int j = 0; j < N; j++) {
matrix[i][j] = rand() % 21 - 10;
}
}
}
void multiply_matrices(const vector<vector<int>>& m1, const
vector<vector<int>>& m2, vector<vector<int>>& result, int start, int end) {
for (int i = start; i < end; i++) {
for (int j = 0; j < N; j++) {
result[i][j] = 0;
for (int k = 0; k < N; k++) {
result[i][j] += m1[i][k] * m2[k][j];
}
}
}
}
void compute_expression(const vector<vector<int>>& m1, const
vector<vector<int>>& m2, const vector<vector<int>>& m3, const
vector<vector<int>>& m4, const vector<vector<int>>& m5, const
vector<vector<int>>& m6, vector<vector<int>>& result, int num_threads) {
vector<vector<int>> m2m3(N, vector<int>(N));
vector<thread> threads;
int block_size = N / num_threads;
for (int i = 0; i < num_threads; i++) {
int start = i * block_size;
int end = (i == num_threads - 1) ? N : (i + 1) * block_size;
Колєснік Д. М. КІ – 20, В.10
threads.push_back(thread(multiply_matrices, ref(m2), ref(m3), ref(m2m3),
start, end));
}
for (auto& th : threads) {
th.join();
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
result[i][j] = m1[i][j] + m2m3[i][j] + m4[i][j] + m5[i][j];
for (int k = 0; k < N; k++) {
result[i][j] += m6[k][j] * (m1[i][k] + m2m3[i][k] + m4[i][k] + m5[i][k]);
}
}
}
}
int main() {
int num_threads;
cout << "Введіть кількість потоків: ";
cin >> num_threads;
vector<vector<int>> m1, m2, m3, m4, m5, m6, result(N, vector<int>(N));
srand(time(nullptr));
generate_matrix(m1);
generate_matrix(m2);
generate_matrix(m3);
generate_matrix(m4);
generate_matrix(m5);
generate_matrix(m6);
auto start_time = chrono::steady_clock::now();
compute_expression(m1, m2, m3, m4, m5, m6, result, num_threads);
Колєснік Д. М. КІ – 20, В.10
auto end_time = chrono::steady_clock::now();
cout << "Час виконання: " <<
chrono::duration_cast<chrono::milliseconds>(end_time - start_time).count() << "
мс" << endl;
return 0;
}
Експеримент:

Висновок:
У ході виконання лабораторної роботи були виконані паралельні обчислення з
використанням декількох потоків та засобів синхронізації на основі
повідомлень.

You might also like