Организация параллельных потоков. Часть 2 | страница 17
Нулевой и первый потоки получили в своё распоряжение по семь итераций, второй поток — шесть. Так что работу поделили почти поровну.
После выхода из параллельной области частичные суммы сложили, да ещё к этой сумме добавили первоначальное значение 10:
S = 7 +7 +6 +10 = 30.
Так работает редукция в параллельном цикле for.
Рис. 4.24. Изменение локальных копий
Задание. Составьте программу (рис. 4.23) и изучите поведение локальных копий общей переменной при распараллеливании цикла с редукцией.
4.3. Вычислительная нагрузка
В этом разделе мы познакомимся с тем, как распределяется вычислительная нагрузка между виртуальными процессорами. Проще говоря, между ядрами процессора.
Наша конечная цель — загрузить все ядра работой на 100%. Только тогда можно будет измерить эффективность распараллеливания.
4.3.1. Полная загрузка
Первый эксперимент — полная загрузка процессора.
Чтобы обеспечить работой все вычислительные элементы процессора, сделаем побольше итераций в нашем цикле. А для этого придётся взять другой целый тип счётчика — «длинное-длинное целое»:
long long.
Это восемь байт, или 8 * 8 = 64 бита. Максимальное значение соответствует 2>64. Для целого числа со знаком получится раза в два поменьше, но всё равно хорошо.
Текст программы с нашей «большой задачей» приведён на рис. 4.25.
Мы объявляем тип счётчика и суммы (строка 4).
Число итераций нашего цикла берём много, но не больше максимально возможного (строка 7).
Тело цикла — прибавление единичек к сумме (строка 8).
Рис. 4.25. «Большая» задача
Компилируем программу и переходим в командную строку.
Задаём количество потоков, равное количеству ядер.
Открываем Диспетчер задач:
Task Manager.
Находим вкладку Быстродействие:
Performance.
Запускаем программу на выполнение и смотрим на загрузку ядер (рис. 4.26).
Каждое ядро загружено на 100%.
Кроме того, в левой части окна показан график общей загрузки процессора в целом — тоже 100%.
Переходим в командное окно и нажимаем комбинацию клавиш для прерывания программы:
Ctrl + C.
Загрузка процессора снова падает почти до нуля.
Рис. 4.26. Полная загрузка всех ядер
Задание. Составьте программу (рис. 4.25) и проведите эксперимент с полной загрузкой всех ядер процессора (рис. 4.26).
4.3.2. Неполная загрузка
Проведём следующий эксперимент.
Уменьшим количество потоков до двух.
Запускаем программу и следим за загрузкой процессора (рис. 4.27).
Видим, что на этот раз все ядра «немного заняты» работой.