Предположим, у нас есть пара массивов в соответствии со следующими объявлениями типов
bool B[ N ];
Bar Foo[ M ];
int B_of_Foo[ M ]; // 0 <= B_of_Foo[m] < N
B
и Foo
могут содержать произвольные значения (в зависимости от контекста), в то время как записи B_of_Foo
содержатограничено индексами от 0
до N-1
.Давайте посмотрим на следующий код:
bool repeat = true
while( repeat ) {
repeat = false;
for( int m = 0; m < M; m++ ) {
if( complicated_condition( Foo[m] ) {
B [ B_of_Foo[ m ] ] = true
repeat |= true;
}
}
}
complicated_condition
- истина, если некоторые И или ИЛИ в Bs верны, а B[ B_of_Foo[ m ] ]
- ложь.Этот код гарантированно завершается при последовательном выполнении.Я хочу распараллелить это с OpenMP.Переменный повтор можно лечить редукцией.Интересно, нужно ли тогда помечать обновление
B [ B_of_Foo[ m ] ] = true
как атомарную операцию.
Я думаю, что любые одновременные или дублированные обновления приведут к тому же результату.Даже если один поток проверяет сложное_условие с устаревшей версией B[ B_of_Foo[ m ] ]
, его последующая операция записи не изменит эту запись B, и код будет стабильным, даже если цикл while повторяется без какого-либо обновления B.