Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаб. 5 ТПП

.docx
Скачиваний:
1
Добавлен:
29.12.2024
Размер:
244.7 Кб
Скачать

Лабораторная работа №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 накладные расходы на синхронизацию выше.

Соседние файлы в предмете Технологии параллельного программирования