Организация параллельных потоков. Часть 1 | страница 8
(Set Affinity).
В разных версиях Windows для задания соответствия используют разные вкладки Диспетчере задач:
— Windows 7 — вкладка Процессы;
— Windows 10 — вкладка Details.
В наших экспериментах можно вставить в начале программы ожидание ввода символа с клавиатуры:
getchar () или __getch ().
После запуска программы она будет ожидать ввода. В этот момент мы изменяем привязку к ядрам. Затем нажимаем Enter на клавиатуре. Далее наша программа будет выполняться на указанных ядрах.
Задание. Запустите Диспетчер задач и обратите внимание на загрузку ядер. Задайте привязку своего процесса к одному ядру или нескольким ядрам. Обратите внимание на изменение загрузки ядер.
5.3. Параллельные потоки и ситуация гонки
Далее мы создадим программу параллельного суммирования. Для знакомства с проблемами распараллеливания будем находить сумму выбранного количества единиц. Затем задача будет постепенно усложняться.
Параллельное обращение к общей ячейке памяти (глобальной переменной) может приводить к нарушению целостности данных. Один поток переписывает содержимое ячейки, не дожидаясь завершения операции другим потоком, то есть фактически «затирает» чужие результаты. Это так называемые «гонки», или соревнование потоков за доступ к данным. Английское название Data Race.
Мы будем изучать ситуацию «гонки» на примере параллельного суммирования (рис. 5.2). Каждый поток в цикле прибавляет единицы к глобальной переменной S. Мы объявляем её до начала модулей программы. Поэтому любой поток может прочитать и записать переменную S.
Если запустить такую программу несколько раз, результаты работы будут непредсказуемыми, случайными.
В текст программы нужно добавить определение времени расчётов.
Рис. 5.2. Параллельное суммирование
Задание. Составьте программу параллельного суммирования (рис. 5.2) и запустите её на выполнение. Откройте Диспетчер задач и обратите внимание на количество потоков в процессе, а также на уровень загрузки виртуальных процессоров. Запустите программу 5 раз и запишите в отчёт продолжительность работы программы, значение суммы и ошибки.
5.4. Критическая секция
Чтобы не допустить ситуацию гонки, используется синхронизация параллельных вычислений с помощью критической секции. Английское название — critical section.
Критическая секция — это часть параллельной программы, которую можно выполнять только последовательно, в одном потоке. Остальные потоки должны дождаться завершения работы в этой частью кода, чтобы выполнить свою работу.