Может ли этот параллельный цикл вызвать гонку данных?

У меня есть std::vector перед параллельным циклом std::pair<Object, bool>, Все bools инициализируются true, Цикл примерно такой:

for (int x = 0; x < xMax; ++x) // can parallelising the loop in x cause a data race?
    for (int y = 0; y < yMax; ++y)
        for (auto& i : vector)
            if (i.first.ConstantFunctionDependingOnlyOnInput(x, y))
                i.second = false;

Так как мы только устанавливаем bool вfalse Я не вижу, что это вызывает гонку данных, но я не доверяю своей интуиции в многопоточности. Операции, выполненные в результате этого bool, впоследствии выполняются в одном потоке (стираются все элементы, где bool == true в векторе с использованием стандартных алгоритмов.

Совет здесь будет оценен. Я собирался использовать std::atomicsно, конечно, они не могут быть использованы в std::vector так как они не копируемы.

Ура!

2 ответа

Решение

Вот пример того, как это может не сработать, и реальный код провалился именно так.

    for (auto& i : vector)
        if (i.first.ConstantFunctionDependingOnlyOnInput(x, y))
            i.second = false;

Компилятор может оптимизировать этот код следующим образом:

for (auto& i : vector);
{
     bool j = i.second;
     bool k = i.first.Function(x, y);
     i.second = k ? false : j;
}

Это может привести к тому, что один поток перезапишет результаты другого потока. Это может быть законной оптимизацией, потому что безусловная запись может быть дешевле, чем условная, поскольку она не может быть ошибочно предсказана.

Вы правы - это будет вести себя точно так, как вы ожидаете (без гонки данных) в любой реальной системе. Хотя официально неопределенное поведение в соответствии со стандартом C++, реальные системы не работают таким образом. Вот ответ на более широкий вопрос, который включает этот.

Вот текст из стандарта, который говорит, что это официально не определено, хотя:

Две оценки выражений конфликтуют, если одна из них изменяет ячейку памяти (1.7), а другая обращается или изменяет ту же ячейку памяти.

Если вы хотите стандартную гарантированную безопасность, вы можете рассмотреть доступ к атомарной памяти.

Другие вопросы по тегам