- •Методичні вказівки
- •"Паралельні та розподілені обчислення"
- •М.Кривий Ріг
- •Основні вимоги та загальні методичні вказівки до виконання лабораторних робіт
- •Лабораторна робота №1 Тема: «Імітація процесу розпаралелювання обчислення суми, добутку, матриць та знаходження коефіцієнтів характеристичного поліному»
- •Концепція необмеженого паралелізму
- •Приклад:
- •Приклад виконання задачі для імітації розпаралелення процесу додавання двох матриць 2х2
- •Звіт повинен містити:
- •Контрольні питання:
- •Лабораторна робота №2 Тема: «Розпаралелювання обчислення суми десяти чисел»
- •Хід роботи
- •Для восьми чисел:
- •Для дев’яти чисел:
- •Особливості програмного інтерфейсу потоків
- •Створення потоків у Win32 арі
- •Завершення потоків у Win32 арі
- •Приєднання потоків у Win32 арі
- •Приклад програми для знаходження суми 8-ми чисел за допомогою процесів без розпаралелення
- •Звіт повинен містити:
- •Контрольні питання:
- •Лабораторна робота №3 Тема: «Розпаралелювання обчислення суми, добутку матриць та знаходження коефіцієнтів характеристичного поліному»
- •Приклад виконання задачі розпаралелювання процесу додавання двох матриць 2х2
- •Звіт повинен містити:
- •Контрольні питання:
- •Лабораторна робота №4 Тема: «Розпаралелювання процесу сортування масивів даних»
- •Теоретичні відомості Мютекси
- •Правила спрощеного паралелізму
- •Приклад програми процесу сортування масиву даних
- •Звіт повинен містити:
- •Контрольні питання:
- •Приклад виконання програми
- •Звіт повинен містити:
- •Контрольні питання:
- •Література
- •Додаток а
- •"Паралельні та розподілені обчислення"
- •6.050102 «Комп’ютерні системи та мережі»
Завершення потоків у Win32 арі
Функцію потоку можна завершити двома способами.
Виконати у ній звичайний оператор return (цей спосіб є найнадійнішим):
unsigned WINAPI thread_fun (void *num) {
return 0:
}
Викликати функцію _endthreadex() з параметром, що дорівнює коду повернення:
unsigned WINAPI thread_fun (void *num) {
_endthreadex(0);
}
Приєднання потоків у Win32 арі
Приєднання потоків у Win32 АРІ, подібно до очікування завершення процесів, здійснюється за допомогою функції WaitForSingleObject(). Базовий синтаксис її використання з потоками такий:
HANDLE th = (HANDLE) _beginthreadex (...);
if (WaitForSingleObject(th. INFINITE) !- WAIT_FAILED) {
//потік завершений успішно
}
CloseHandle(th);
Приклад програми для знаходження суми 8-ми чисел за допомогою процесів без розпаралелення
Листинг програми
#include <windows.h>
#include <process.h>
#include <iostream.h>
#include <conio.h>
#include <vcl.h>
int number1 = 9,number2 = 1,numb=0;
int proc1,proc2,k=0,mem[10];
unsigned tid;
HANDLE Thread[8];
DWORD res;
int i,p=2,A,B,a[8];
unsigned __stdcall Sum( void * arg) // Функція потоку
{
proc1=a[k];
proc2=a[k+1];
mem[k]=proc1+proc2;
cout<<"Комірка памяті[ "<<i<<" ]"<<mem[k]<<endl;
k+=2;
return 0;
};
unsigned __stdcall Sum2( void * arg) // Функція потоку
{
proc1=mem[k];
proc2=mem[k+p];
mem[k]=proc1+proc2;
cout<<"Комірка памяті[ "<<i<<" ]"<<mem[k]<<endl;
k+=4;
return 0;
};
int main()
{ SetConsoleOutputCP(1251);
cout<<"Введіть кількість чисел (до восьми)\n";
cin>>A;
cout<<"Введіть числа\n";
for (i=0;i<8;i++){
a[i]=0;
}
for (i=0;i<A;i++){
cin>>a[i];
}
for (i=0;i<4;i++){
Thread[i] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid);
Sleep(10);
}
// Чекаємо, доки потоки не завершать свою работу
WaitForMultipleObjects(4, Thread, TRUE, INFINITE );
cout<<"Потоки завершили виконання"<<endl;
for (i=0;i<8;i++){
CloseHandle(Thread[i]);
}
k=0;
for (i=0;i<2;i++){
Thread[i] = (HANDLE)_beginthreadex(NULL, 0, Sum2, 0, 0, &tid);
Sleep(10);
}
// Чекаємо, доки потоки не завершать свою работу
WaitForMultipleObjects(2, Thread, TRUE, INFINITE );
cout<<"Потоки завершили виконання"<<endl;
for (i=0;i<2;i++){
CloseHandle(Thread[i]);
}
//for (i=0;i<10;i++)cout<<mem[i]<<endl;
p=4;k=0;i=0;
Thread[1] = (HANDLE)_beginthreadex(NULL, 0, Sum2, 0, 0, &tid);
Sleep(10);
cout<<"Потоки завершили виконання"<<endl;
CloseHandle(Thread[1]);
getch();
return 0;
}
Дана програма виконує знаходження суми вектору чисел, який складається не більш ніж з 8-ми елементів за допомогою потоків. Ми маємо масив а[ ] та комірки пам’яті mem. Якщо маємо масив з восьми елементів {1,2,3,4,5,6,7,8} то знайдемо суми сусідніх елементів {3,7,11,15}, і так далі до знаходження остаточного результату.
Введіть кількість чисел (до восьми)
8
Введіть числа
1
2
3
4
5
6
7
8
Комірка пам’яті [ 0 ]3
Комірка пам’яті [ 1 ]7
Комірка пам’яті [ 2 ]11
Комірка пам’яті [ 3 ]15
Потоки завершили виконання
Комірка пам’яті [ 0 ]10
Комірка пам’яті [ 1 ] 26
Потоки завершили виконання
Комірка пам’яті [ 0 ]36
Потоки завершили виконання
Рисунок 2.5 – Приклад виконання програми
Стан пам’яті під час виконання програми:
Mem1 |
Mem2 |
Mem3 |
Mem4 |
Mem5 |
Mem6 |
Mem7 |
Mem8 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
3 |
0 |
7 |
0 |
11 |
0 |
15 |
0 |
10 |
0 |
7 |
0 |
26 |
0 |
15 |
0 |
36 |
0 |
7 |
0 |
26 |
0 |
15 |
0 |
З рисунків 2.5, 2.6 видно, що програма складається з 3-х ярусів:
Алгоритм розпаралелення:
Рисунок 2.6 – Схема розпаралелення процесу
На першому ярусі за допомогою чотирьох процесорів знаходимо суму елементів а1+а2, а3+а4, а5+а6, а7+а8. Після чого результати заносимо в пам'ять.
На другому ярусі знаходимо суму даних з комірок пам’яті mem[1]+mem[3], mem[5]+mem[7], після чого результати заносимо в пам'ять.
На третьому ярусі знаходимо суму даних з комірок пам’яті mem[1]+mem[5].