Теория распараллеливания и синхронизация. Демьянович Ю.К - 62 стр.

UptoLike

которое опять-таки приведет к конфликтам в памяти, ибо сумму
вычисляет каждый процесс. Таким образом, это решение неэффек-
тивно.
Обе проблемы онфликтов обращения к памяти и обнуления
массива) могут быть решены использованием управляющего про-
цесса.
Пусть имеется набор n процессов Worker[i], i = 1, . . . , n, и
один процесс Coordinator. Каждый процесс Worker[i] ждет, по-
ка элемент continue[i] примет значение 1, где continue[1 : n]
дополнительный массив с нулевыми начальными значениями: сна-
чала (по прибытию к барьеру) процесс Worker[i] делает присва-
ивание arrive[i] = 1, а затем ожидает момента, когда окажется,
что continue[i] == 1, и лишь после этого он продолжает рабо-
ту. Приведем соответствующий фрагмент программы для процесса
Worker[i]:
arrive[i] = 1;
< await (continue[i] == 1); >
Что касается процесса Coordinator, то он сначала ждет, пока все
значения элементов массива arrive станут равными 1, а затем
присваивает всем элементам continue значения 1, тем самым про-
пуская через барьер процессы Worker[i]. Соответствущий фрагмент
программы для процесса Coordinator таков:
for [i = 1 to n] < await (arrive[i] == 1); >
for [i = 1 to n] continue[i] = 1;
Операторы await можно реализовать в виде циклов
while . . . skip, т.к. в каждом случае ссылка происходит лишь на
одну разделяемую переменную.
Заметим, что Coordinator может проверять установку элемен-
тов arrive[i] в единицу в любом порядке; при этом конфликтов
обращения к памяти не будет, поскольку процессы ожидают изме-
нения различных переменных, каждая из которых хранится в своей
строке кэш-памяти.
Фактически переменные arrive[i], continue[i] являются при-
мерами флагов, которые “поднимаются” и “сбрасываются” процес-
сами, что соответствует их установке в 1 и в 0 соответственно. В
63