Министерство науки и высшего образования РФ Федеральное государственное бюджетное образовательное учреждение высшего образования Рязанский государственный радиотехнический университет имени В.Ф. Уткина Кафедра ЭВМ Отчет по практическому занятию № 1 «Модель вычислений и классы переменных» Рязань 2023 Задание 1. Определите, какую версию стандарта OpenMP поддерживает компилятор в вашей системе. 2. Выполните приведенные ниже примеры и объясните полученные результаты Ход работы 1. Параллельная область на языке Си #include <stdio.h> #include<locale.h> #include <omp.h> int main() { setlocale(LC_ALL, "RUS"); printf("Последовательная область 1\n"); #pragma omp parallel { printf("Параллельная область\n"); } printf("Последовательная область 2\n"); return 0; } Результат представлен на рисунке 1. Рисунок 1 – Параллельная область 2 Сколько потоков порождается в этом примере? Количество потоков в ОС Можно ли изменить количество потоков? Да. 1) Опция num_threads директивы parallel (#pragma omp parallel num_threads(3)) 2) Функция omp_set_num_threads(int value) 3) Переменная окружение OMP_NUM_THREADS 2. Опция private на языке Си #include <omp.h> #include <iostream> int main() { system("chcp 1251>nul"); // Изменение кодировки консоли int n = 1; printf("n в последовательной области (начало): %d\n", n); #pragma omp parallel num_threads(4) private(n) { printf("Значение n на нити (на входе): %d\n", n); n = omp_get_thread_num(); printf("Значение n на нити (на выходе): %d\n", n); } printf("n в последовательной области (конец): %d\n", n); system("pause>nul"); // Задержка консольного окна return 0; } Результат представлен на рисунке 2. Рисунок 2 – Опция private 3. Опция shared на языке Си #include <omp.h> #include <iostream> int main() { system("chcp 1251>nul"); int i, m[10]; printf("Массив m в начале:\n"); for (i = 0; i < 10; i++) { m[i] = 0; printf("%d\n", m[i]); } #pragma omp parallel num_threads(4) shared(m) { m[omp_get_thread_num()] = 1; } printf("Массив m в конце:\n"); for (i = 0; i < 10; i++) printf("%d\n", m[i]); return 0; } 3 Результат представлен на рисунке 3. Рисунок 3 – Опция shared 4. Опция firstprivate на языке Си #include <omp.h> #include <iostream> int main() { system("chcp 1251>nul"); omp_set_num_threads(4); int n = 1; printf("Значение n в начале: %d\n", n); #pragma omp parallel firstprivate(n) { printf("Значение n на нити (на входе): %d\n", n); n = omp_get_thread_num(); printf("Значение n на нити (на выходе): %d\n", n); } printf("Значение n в конце: %d\n", n); return 0; } Результат выполнения представлен на рисунке 4. Рисунок 4 – Опция firstprivate 4 5. Директива threadprivate на языке Си #include <omp.h> #include <iostream> int n; #pragma omp threadprivate(n) int main() { system("chcp 1251>nul"); omp_set_num_threads(4); int num; n = 1; #pragma omp parallel private (num) { num = omp_get_thread_num(); printf("Значение n на нити %d (на входе): %d\n", num, n); n = omp_get_thread_num(); printf("Значение n на нити %d (на выходе): %d\n", num, n); } printf("Значение n (середина): %d\n", n); #pragma omp parallel private (num) { num = omp_get_thread_num(); printf("Значение n на нити %d (ещё раз) : %d\n", num, n); } return 0; } Результат выполнения представлен на рисунке 5. Рисунок 5 – Директива threadprivate 6. Функция omp_set_num_threads() и опция num_threads на языке Си #include <omp.h> #include <iostream> int main() { system("chcp 1251>nul"); omp_set_num_threads(5); #pragma omp parallel num_threads(3) { printf("Параллельная область 1\n"); } #pragma omp parallel { printf("Параллельная область 2\n"); } return 0; } 5 Результат выполнения представлен на рисунке 6. Рисунок 6 – Функция omp_set_num_threads() и опция num_threads Заключение В ходе работы были рассмотрены модель вычислений и классы переменных openMP. 6