
Лаб. 5 ТПП
.docxЛабораторная работа №5
Распределение вычислительной нагрузки
Цель: изучить основные особенности распределения вычислительной нагрузки в OpenMP на примере использования в рамках языка С++.
Задание:
Лабораторная работа №5
Распределение вычислительной нагрузки
Цель: изучить основные особенности распределения вычислительной нагрузки в OpenMP на примере использования в рамках языка С++.
Задание:
#include <iostream>
#include <omp.h>
#include <iomanip>
#include <cstdlib>
const int N = 100000;
using namespace std;
int main() {
setlocale(LC_ALL, "Rus");
cout << "N: " << N << endl << endl;
int i;
int* a = new int[N];
int* b = new int[N];
int* c = new int[N];
srand(static_cast<unsigned int>(time(nullptr)));
for (i = 0; i < N; i++)
{
a[i] = rand() % 21 - 10;
b[i] = rand() % 21 - 10;
}
double start_time0 = omp_get_wtime();
long total0 = 0;
#pragma omp parallel num_threads(2) shared(a,b,c) reduction(+:total0)
{
#pragma omp for private(i)
for (i = 0; i < N; i++)
{
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total0 += c[i];
}
}
double end_time0 = omp_get_wtime();
cout << "2 потока" << endl;
cout << "Итоговая сумма: " << total0 << endl;
cout << "Время выполнения: " << fixed << setprecision(16) << (end_time0 - start_time0) << " секунд" << endl;
double start_time04 = omp_get_wtime();
long total04 = 0;
#pragma omp parallel num_threads(4) shared(a,b,c) reduction(+:total04)
{
#pragma omp for private(i)
for (i = 0; i < N; i++)
{
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total04 += c[i];
}
}
double end_time04 = omp_get_wtime();
cout << "4 потока" << endl;
cout << "Итоговая сумма: " << total04 << endl;
cout << "Время выполнения: " << fixed << setprecision(16) << (end_time04 - start_time04) << " секунд" << endl;
double start_time = omp_get_wtime();
long total = 0;
//#pragma omp parallel num_threads(16) shared(a, b, c, total)
// {
#pragma omp parallel sections shared(a, b, c) private(i) reduction(+:total) //num_threads(2)
{
#pragma omp section
{
int z = omp_get_num_threads();
int p = omp_get_thread_num();
for (i = 0; i < N / 2; i++) {
//printf("Поток %d\n", p);
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total += c[i];
}
//printf("Кол потоков %d\n", z);
}
#pragma omp section
{
int z = omp_get_num_threads();
int p = omp_get_thread_num();
for (i = N / 2; i < N; i++) {
//printf("Поток %d\n", p);
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total += c[i];
}
//printf("Кол потоков %d\n", z);
}
}
// }
double end_time = omp_get_wtime();
cout << "2 секции" << endl;
cout << "Итоговая сумма: " << total << endl;
cout << "Время выполнения: " << fixed << setprecision(16) << (end_time - start_time) << " секунд" << endl;
double start_time2 = omp_get_wtime();
long total2 = 0;
//#pragma omp parallel num_threads(16) shared(a, b, c, total2)
// {
#pragma omp parallel sections shared(a, b, c) private(i) reduction(+:total2) //num_threads(4)
{
#pragma omp section
{
int z = omp_get_num_threads();
int p = omp_get_thread_num();
for (i = 0; i < N / 4; i++) {
//printf("Поток %d\n", p);
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total2 += c[i];
}
//printf("Кол потоков %d\n", z);
}
#pragma omp section
{
int z = omp_get_num_threads();
int p = omp_get_thread_num();
for (i = N / 4; i < N / 2; i++) {
//printf("Поток %d\n", p);
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total2 += c[i];
}
//printf("Кол потоков %d\n", z);
}
#pragma omp section
{
int z = omp_get_num_threads();
int p = omp_get_thread_num();
for (i = N / 2; i < 3 * N / 4; i++) {
//printf("Поток %d\n", p);
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total2 += c[i];
}
//printf("Кол потоков %d\n", z);
}
#pragma omp section
{
int z = omp_get_num_threads();
int p = omp_get_thread_num();
for (i = 3 * N / 4; i < N; i++) {
//printf("Поток %d\n", p);
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total2 += c[i];
}
//printf("Кол потоков %d\n", z);
}
}
// }
double end_time2 = omp_get_wtime();
cout << "4 секции" << endl;
cout << "Итоговая сумма: " << total2 << endl;
cout << "Время выполнения: " << fixed << setprecision(16) << (end_time2 - start_time2) << " секунд" << endl;
/*
double start_time3 = omp_get_wtime();
long total3 = 0;
for (i = 0; i < N; i++)
{
if (a[i] > b[i])
c[i] = a[i];
else
c[i] = b[i];
total3 += c[i];
}
double end_time3 = omp_get_wtime();
cout << "однопоток" << endl;
cout << "Итоговая сумма: " << total3 << endl;
cout << "Время выполнения: " << fixed << setprecision(16) << (end_time3 - start_time3) << " секунд" << endl;
*/
delete[] a;
delete[] b;
delete[] c;
return 0;
}
Использование потоков может приводить к неравномерному распределению нагрузки между потоками. Создание и управление потоками требует времени.
С потоками reduction накладные расходы на синхронизацию выше.