компилятор выдает мне неверную ошибку формы для omp atomic.
Прагма atomic
не может свободно применяться ни к какому утверждению.Разрешены только конкретные формы утверждений, в зависимости от того, какой тип атомарного предложения вы используете.Если вы не укажете ароматизатор, вы получите аромат «обновление», для которого требуется выражение выражения (пока все хорошо) с одной из следующих форм:
x++;
x--;
++x;
--x;
x binop= expr;
x = x binop expr;
x = expr binop x;
, где binop
представляетодин из операторов +
, *
, -
, /
, &
, ˆ
, |
, <<
или >>
.Есть и другие требования;см. раздел 2.13.6 спецификации OpenMP .Ни одно из утверждений, которые вы пытаетесь объявить атомарными, не удовлетворяет этим требованиям.
Но разве не получается то же самое?Есть какие-нибудь указания, чтобы получить то же самое?
Выше приведены объяснения предупреждений, но даже если эти формы были разрешены, вы, похоже, ожидаете от atomic
большего, чем удовлетворяет OpemMP.Для правильно сформированной атомарной операции это доступ к определенной ячейке памяти, обозначенной x
выше, - это атомарная, а не выполнение всего оператора.Ваши x
, y
и z
уже закрыты, поэтому их обновление в атомном режиме ничего не даст вам.Однако, если state
является общей переменной (в отличие от того, когда вы ее объявили firstprivate
), у вас есть условия гонки, связанные с доступом к ней, и поэтому поведение вашей программы не определено.
Я полагаю, что вы ожидаетерезультаты взяты из вашего альтернативного кода, в котором state
объявлен firstprivate
, но даже если ваши обращения к state
были правильно синхронизированы - например, путем помещения их в omp critical
разделы - это не будет разумноожидать тех же результатов, потому что вы будете выполнять другие вычисления.Более того, детали результата (вероятно) будут зависеть от порядка планирования потоков.
Моя цель - использовать атомарный или критический в openMP и добиться того же результата, что и при использовании firstprivate (State) в следующем коде
Вы не можете.Как уже было описано, хотя вы можете использовать critical
разделы для разрешения ваших гонок данных, результирующий ряд вычислений отличается от того, который был получен с помощью firstprivate(state)
, и, кроме того, зависит от планирования потоков.Нет никаких оснований ожидать одинаковых результатов.
Кроме того, помещение критических секций в такой узкий цикл почти наверняка убьет любое преимущество в производительности из-за распараллеливания.Я ожидал бы, что параллельные версии будут быстрее становиться медленнее, чем последовательные версии, так как количество потоков увеличивается, возможно, даже с двумя потоками.