语法形式原子的无效形式

时间:2019-06-28 03:03:48

标签: c openmp

我的目标是在openMP中使用原子的或关键的原子,并获得与以下代码中使用firstprivate(state)相同的结果,但是编译器抛出的错误是omp原子的形式错误。

代码如下:

        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 个答案:

答案 0 :(得分:1)

  

编译器抛出omp原子无效的格式错误。

atomic编译指示不适用于任何语句。仅允许使用特定形式的语句,具体取决于您使用哪种原子子句。如果未指定风味,则将获得“更新”风味,它需要使用以下形式之一的表达式语句(到目前为止非常好):

x++;
x--;
++x;
--x;
x binop= expr;
x = x binop expr;
x = expr binop x;

,其中binop代表运算符+*-/&ˆ中的一个,|<<>>。还有更多的要求。参见the OpenMP specification的第2.13.6节。您尝试声明为atomic的语句均未满足这些要求。

  

但是不一样吗?有获得相同指示的任何指示吗?

以上解释了警告,但是即使允许使用这些表格,您对atomic的期望似乎也比OpemMP更高。对于格式正确的原子操作,这是对特定存储位置(即上述x指定)的访问,这是原子的,而不是整个语句的执行。您的xyz已经是私有的,因此原子地更新它们不会给您带来任何好处。但是,state是一个共享变量(与声明它firstprivate时相反),您会遇到涉及对其进行访问的竞争条件,因此程序的行为是不确定的。

我想您的预期结果来自您在其中state被声明为firstprivate的替代代码中获得的结果,但是即使您对state的访问已正确同步-通过将其放入{例如,{1}}节-期望得到相同的结果是不合理的,因为您将执行不同的计算。此外,结果的详细信息(可能)取决于线程调度的顺序。

  

我的目标是在openMP中使用原子的或关键的,并获得与以下代码中使用firstprivate(state)相同的结果

不能。如前所述,尽管您可以使用omp critical部分来解决数据争用,但是所得的一系列计算与critical所获得的计算有不同的,而且取决于线程调度。没有理由期望获得相同的结果。

此外,将关键部分置于如此紧密的循环中几乎肯定会消除并行化带来的任何性能优势。我希望随着线程数量的增加,甚至只有两个线程,并行版本会比串行版本迅速变慢。

答案 1 :(得分:0)

由于您没有在omp atomic构造中指定 atomic-clause ,它将假定您想要update。您的表达式语句不是更新语句。

您的omp指令应使用的是

#pragma omp atomic write

但是,由于xyz都是局部变量,因此每个线程将具有其自己的副本,并且不需要原子构造。调用ran2原子是不起作用的;只有结果分配。