Неправильная форма атомной прагмы - PullRequest
0 голосов
/ 28 июня 2019

Моя цель - использовать атомарный или критический в openMP и добиться того же результата, что и при использовании firstprivate (state) в следующем коде, но компилятор выдает мне неверную ошибку формы для omp atomic.

Вот код:

        omp_set_dynamic(0);
        omp_set_num_threads(threads[y]);
        #pragma omp parallel for reduction(+:count) private(i)
        for(i=1;i<=niter;i++){
            double x, y, z;
            long seed;
            seed=i;
            #pragma omp atomic
            x=ran2(&seed, &state);
            #pragma omp atomic
            y=ran2(&seed, &state);
            #pragma omp atomic
            z=x*x+y*y;
            if(z<1){
                count+=1;
            }
        }

Ожидаемый результат:

The value of pi for 1 threads is 3.14320000000000
The value of pi for 2 threads is 3.13320000000000
The value of pi for 4 threads is 3.12400000000000
The value of pi for 8 threads is 3.14680000000000
The value of pi for 16 threads is 3.15880000000000

Но не получается то же самое? Любые направления, чтобы получить то же самое?

Ответы [ 2 ]

1 голос
/ 28 июня 2019

компилятор выдает мне неверную ошибку формы для 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), и, кроме того, зависит от планирования потоков.Нет никаких оснований ожидать одинаковых результатов.

Кроме того, помещение критических секций в такой узкий цикл почти наверняка убьет любое преимущество в производительности из-за распараллеливания.Я ожидал бы, что параллельные версии будут быстрее становиться медленнее, чем последовательные версии, так как количество потоков увеличивается, возможно, даже с двумя потоками.

0 голосов
/ 28 июня 2019

Поскольку вы не указываете атомарное предложение в своей конструкции omp atomic, он будет предполагать, что вы хотите update. Вы выражения выражения не являются обновлениями заявления.

Что вы должны использовать для своей директивы omp

#pragma omp atomic write

Однако, поскольку x, y и z являются локальными переменными, каждый поток будет иметь свою собственную копию, и атомарная конструкция не требуется. Не будет работать звонить на ran2 atomic; будет только присвоение результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...