Валентин Арьков - Организация параллельных потоков. Часть 2
- Название:Организация параллельных потоков. Часть 2
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:2020
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Валентин Арьков - Организация параллельных потоков. Часть 2 краткое содержание
Параллельные программы нужны для того, чтобы использовать вычислительные мощности многоядерных процессоров и графических ускорителей. В данной работе мы рассмотрим технологию автоматической организации параллельных потоков для многоядерных вычислительных машин.
Организация параллельных потоков. Часть 2 - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Для одной программы можно использовать два или три способа одновременно.
При этом существует приоритет (относительная важность) настроек. Какая-то настройка важнее другой, и она отменяет менее важную настройку, заменяет своим параметром.
Задание.Проверьте все комбинации настроек и сделайте выводы о приоритете настроек.
4. Управление распараллеливанием
Мы познакомились с основными инструментами создания параллельных программ. Теперь немного углубимся в управление параллельными потоками.
4.1. Вычислительная среда
Чтобы эффективно распараллелить решение задачи, нужно разделить большую задачу на части и раздать эти части параллельным потокам. При этом и главный поток, и каждый поток в группе должны в момент выполнения сориентироваться в обстановке. Нам нужно изнутри программы получить определённые сведения, например, такие:
— число процессоров в компьютере;
— число потоков в группе;
— номер текущего потока в группе.
4.1.1. Число процессоров
Начнём с числа процессоров.
Напомним, что слово «процессор» в нашем случае — это указание на «виртуальный процессор». Другими словами, это любой вычислительный элемент, который может выполнять один поток. Физическая реализация сейчас не важна.
Число «процессоров» можно узнать с помощью библиотечной функции
int omp_get_num_procs (void).
Функция возвращает количество доступных процессоров. Доступных именно нашей программе, а точнее ПРОЦЕССУ. В предыдущей работе мы уже немного познакомились с привязкой процесса к конкретным ядрам.
Создадим новую программу и познакомимся с описанной функцией (рис. 4.1).
Рис. 4.1. Число доступных процессоров
Запускаем программу и видим сообщение (рис. 4.2).
Убеждаемся, что заявленное число процессоров соответствует действительности.
Рис. 4.2. Число процессоров
Задание.Создайте и запустите программу (рис. 4.1). Проверьте, как изменится сообщение программы, если установить число процессоров через параметр окружения NUMBER_OF_PROCESSORSи запустить программу в командной строке.
4.1.2. Число потоков
Рассмотрим, как узнать число потоков в текущей параллельной области программы.
Для организации параллельной работы нужно знать, на сколько частей делить задачу. И вообще, надо следить за событиями. Даже если всё как бы само собой делается, за результаты отвечает почему-то не компьютер, а программист.
Итак, вот библиотечная функция, которая сообщает нам количество параллельных потоков в группе:
int omp_get_num_threads (void).
Расшифровывается название так:
Number of Threads — «число потоков».
Аргументов у функции нет, но скобки при вызове придётся использовать.
Вторая полезная библиотечная функция сообщает номер текущего потока в группе:
int omp_get_thread_num (void).
Название расшифровывается так:
Thread Number — «номер потока».
Номера потоков начинаются с нуля. Это будет главный поток.
Соответственно, максимальный номер потока равен числу потоков минус один.
Названия этих двух функций очень похожи, здесь просто другой порядок слов.
Судите сами:
num_threads / thread_num.
Придётся немного освежить английский. Здесь действует так называемое «правило ряда» (цепочка определений). Если идут несколько существительных подряд, то главное слово будет в конце.
Вторая трудность с пониманием названий — слово NUMBER. Оно может означать «количество» или «порядковый номер». Это одно и то же слово, но два разных значения. И переводятся разные значения разными словами. Вообще-то у этого слова ещё штук двадцать других значений, но дальше углубляться мы уже не будем.
Составим программу и посмотрим, как работают эти две функции (рис. 4.3).
Для организации вывода в виде таблицы используем символ табуляции:
\t.
Табуляция смещает начало вывода на 8 позиций.
Таким образом, первое число выводится начиная с 1-й позиции, второе число — с 9-й и т. д.
Табуляция нам ещё пригодится для анализа эффективности и точности.
Рис. 4.3. Номер потока и количество потоков
Запускаем программу и видим сообщения в произвольном порядке (рис. 4.4). Кто первый успел — тот и напечатал. Если запускать программу несколько раз, получим разные результаты.
Рис. 4.4. Список номеров потоков
Задание.Составьте программу (рис. 4.3). Запустите программу несколько раз и обратите внимание на порядок вывода номеров потоков.
4.2. Параллельный цикл
В этом разделе мы организуем параллельное исполнение цикла FOR и исследуем поведение программы. Результаты могут оказаться не совсем очевидными. Это особенности параллельного программирования. Вот с этими особенностями нам и предстоит познакомиться.
4.2.1. Ситуация гонки
При выполнении параллельной программы может возникать так называемая «ситуация гонки». Это соревнование параллельных потоков за доступ к данным. Английское название:
Data Race.
Мы её уже рассматривали в предыдущей работе. Параллельные потоки обращаются к общей переменной и «затирают» чужие результаты, записывая свои. В результате появляется ошибка в расчётах. Причём ошибка будет случайной, непредсказуемой, и при каждом запуске ошибка будет разной.
Начнём с решения задачи распараллеливания цикла «в лоб».
Рассмотрим программу вычисления суммы большого количества единиц в цикле (рис. 4.5).
Перед оператором цикла вставляем следующую строчку:
#pragma omp parallel for(строка 6).
Эта директива организует параллельное выполнение разных итераций цикла несколькими потоками.
Рис. 4.5. Параллельный цикл
В нашей программе все параллельные потоки будут работать с одной общей переменной S. Для последовательной программы это не представляет каких-то проблем.
Запускаем командное окно и переходим в каталог с исполняемым файлом.
Задаём выполнение в один поток:
set OMP_NUM_THREADS=1.
Запускаем программу несколько раз (рис. 4.6).
Видим, что результат каждый раз получается правильный. Он соответствует количеству итераций цикла, заданному в нашей программе.
Рис. 4.6. Запуск одного потока
Задание.Создайте программу (рис. 4.5) и запустите её несколько раз. Обратите внимание на полученные результаты.
Попробуем запускать программу несколько раз, не загромождая экран лишним текстом. Для этого создадим пакетный файл (рис. 4.7).
Напомним, что пакетный файл — это текстовый файл, в котором вызываются команды операционной системы. То, что мы обычно набираем в командной строке вручную. Здесь также можно использовать дополнительные команды, напоминающие привычный язык программирования.
Читать дальшеИнтервал:
Закладка: