При выполнении параллельной программы может возникать так называемая «ситуация гонки». Это соревнование параллельных потоков за доступ к данным. Английское название:
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).
Напомним, что пакетный файл — это текстовый файл, в котором вызываются команды операционной системы. То, что мы обычно набираем в командной строке вручную. Здесь также можно использовать дополнительные команды, напоминающие привычный язык программирования.
В первой строчке пакетного файла мы отключаем вывод на экран вводимой команды:
@echo off.
В следующих строчках мы несколько раз запускаем нашу программу на выполнение. Расширение имени файла EXEне указываем.
Сохраняем файл в каталоге Release — там же, где находится наш исполняемый файл. Указываем имя файла 08 и расширение имени CMD. Это сокращение от слова COMMAND. Можно также использовать традиционное расширение BAT — от слова BATCH — «пакетный файл».
Рис. 4.7. Пакетный файл
Задание.Создайте пакетный файл (рис. 4.7).
Возвращаемся в командное окно. Переходим в каталог Releaseнашего текущего проекта (рис. 4.8). Вводим команду dir. Убеждаемся, что в текущем каталоге появился пакетный файл 08.cmd. Здесь же видим нас исполняемый файл с расширением EXE.
Рис. 4.8. Каталог Release
Запускаем наш пакетный файл. Вводим название файла, не указывая его расширение:
08.
Программа запускалась десять раз. Во всех случаях ответ правильный (рис. 4.9).
Рис. 4.9. Пакетный запуск программы
Задание.Запустите пакетный файл и изучите полученные результаты.
Мы создали первый пакетный файл и ввели нашу команду несколько раз. В пакетном файле можно организовать цикл. Традиционный цикл FORсо счётчиком. Тогда файл получается покороче и попроще.
Первая строчка отменяет вывод выполняемых команд на экран — как в предыдущем примере:
@echo off.
Вторая строчка — цикл FOR.
Имя счётчика цикла в пакетном файле начинается с двух символов процента:
%%i.
Ключ /Lпозволяет указать диапазон значений счётчика и шаг изменения.
Далее мы указываем диапазон значений — от единицы до десяти с единичным шагом:
(1, 1, 10).
Тело цикла — наша команда — запуск программы на выполнение.
Запускаем пакетный файл (рис. 4.10).
Результаты нас устраивают.
Последовательное выполнение программы не даёт ошибок в расчётах.
Рис. 4.10. Цикл в пакетном файле
Задание.Создайте пакетный файл (рис. 4.10) и запустите его.
Теперь запустим несколько потоков.
Установим три потока:
set OMP_NUM_THREADS=3.
Запускаем пакетный файл.
Получаем десять разных результатов (рис. 4.11).
За возникновение таких нежелательных ситуаций отвечает программист. Так что составление параллельных программ требует дополнительного обучения.
Рис. 4.11. Результаты гонки
Задание.Запустите пакетный файл, задавая разное количество параллельных потоков. Обратите внимание на ошибки в расчётах.
Читать дальше
Конец ознакомительного отрывка
Купить книгу