
- •Задание 1 и 2:
- •Контрольные вопросы:
- •В чем состоят основы технологии OpenMp?
- •В чем состоят основные преимущества и недостатки технологии OpenMp?
- •В чем состоят понятия фрагмента, области и секции параллельной программы?
- •Как осуществляется распараллеливание циклов в OpenMp? Какие условия должны выполняться, чтобы циклы могли быть распараллелены?
- •Какие возможности имеются в OpenMp для управления распределением итераций циклов между потоками?
- •Как определяется порядок выполнения итераций в распараллеливаемых циклах?
Лабораторная работа №1
Распараллеливание по данным для циклов
Цель: изучить основные особенности распараллеливания данных по циклам в OpenMP на примере использования в рамках языка С++.
Пример 1:
#include <iostream>
#include <omp.h> // заголовочный файл «omp.h»
void main() {
/* Выделение параллельного фрагмента*/
#pragma omp parallel //num_threads(12)
{
int thread_id = omp_get_thread_num();
//printf("%d Hello World !\n", i);
printf("%d Hello World !\n", thread_id);
}
/* Завершение параллельного фрагмента */
}
Пример 2:
#include <iostream>
#include <omp.h>
const int NMAX = 100;
void main()
{
setlocale(LC_ALL, "Rus");
int i, j;
float sum;
float a[NMAX][NMAX];
for (i = 0; i < NMAX; i++)
for (j = 0; j < NMAX; j++)
a[i][j] = i + j;
// инициализация данных
#pragma omp parallel shared(a) private(i)
{
#pragma omp for private(j,sum)
for (i = 0; i < NMAX; i++)
{
sum = 0;
for (j = 0; j < NMAX; j++)
sum += a[i][j];
printf("Сумма элементов строки %d равна %f\n", i, sum);
}
} /* Завершение параллельного фрагмента */
}
Задание 1 и 2:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <omp.h>
#include <chrono>
#include <iomanip>
//const int M = 800;
//const int N = 500;
using namespace std;
int countSevens(int number) {
int count = 0;
while (number > 0) {
if (number % 10 == 7) {
count++;
}
number /= 10;
}
return count;
}
int main() {
setlocale(LC_ALL, "Rus");
int sum = 0;
int i, j, k;
int M, N;
cout << "Введите количество строк (M): ";
cin >> M;
cout << "Введите количество столбцов (N): ";
cin >> N;
// Инициализация генератора случайных чисел
srand(static_cast<unsigned int>(time(nullptr)));
// Создание матрицы
int** matrix = new int* [M];
for (int i = 0; i < M; ++i) {
matrix[i] = new int[N];
for (int j = 0; j < N; ++j) {
matrix[i][j] = rand() % 100 + 1; // случайные натуральные числа от 1 до 100
}
}
/*
int matrix[M][N];
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
matrix[i][j] = rand() % 100 + 1;
//matrix[i][j] = i + j;
}
}
*/
// Вывод матрицы на экран
/*
cout << "Сгенерированная матрица:" << endl;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
*/
// Параллельный подсчет семёрок
long totalCount = 0;
double start_time = omp_get_wtime(); // Начало замера времени
#pragma omp parallel shared(matrix) private(i) reduction(+:totalCount)
{
#pragma omp for private(j, k, sum)
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
for (k = j + 1; k < N; k++) {
sum = matrix[i][j] + matrix[i][k];
totalCount += countSevens(sum);
}
}
//cout << "Количество семёрок в "<< i << " строке: " << totalCount << endl;
printf("Количество семёрок в %d строке: %d\n", i, totalCount);
}
}
double end_time = omp_get_wtime(); // Конец замера времени
cout << "Задание 1" << endl;
cout << "Общее количество семёрок: " << totalCount << endl;
cout << "Время выполнения: " << (end_time - start_time) << " секунд" << endl;
int totalCount2 = 0;
auto start_time2 = chrono::high_resolution_clock::now();
sum = 0;
int count;
for (i = 0; i < M; i++) {
count = 0;
for (j = 0; j < N; j++) {
for (k = j + 1; k < N; k++) {
int a = 0;
sum = matrix[i][j] + matrix[i][k];
a = countSevens(sum);
totalCount2 += a;
count += a;
}
}
//cout << "Количество семёрок в " << i << " строке: " << totalCount2 << endl;
printf("Количество семёрок в %d строке: %d\n", i, count);
}
auto end_time2 = chrono::high_resolution_clock::now(); // Конец замера времени
chrono::duration<double> duration = end_time2 - start_time2;
cout << fixed << setprecision(7); // 7 знаков после запятой
cout << "Задание 2" << endl;
cout << "Общее количество семёрок: " << totalCount2 << endl;
cout << "Время выполнения: " << duration.count() << " секунд" << endl;
for (int i = 0; i < M; i++) {
delete[] matrix[i];
}
delete[] matrix;
return 0;
}