Организация параллельных потоков. Часть 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).

Видим, что на этот раз все ядра «немного заняты» работой.