openmp,内联函数和静态变量(普通C)

时间:2016-09-05 09:26:30

标签: c openmp

版本1:

inline double func(int i){
    double X;
    X=sqrt(2)*i;
    return X;
}

版本2:

inline double func(int i){
    static double X;
    X=sqrt(2)*i;
    return X;
}

版本3:

inline double func(int i){
    static double X;
    #pragma omp threadprivate(X)
    X=sqrt(2)*i;
    return X;
}

然后在openmp块内调用func()函数,例如:

#pragma omp for default(shared) private(i) schedule(static)
for(i=istart;i<istop;i++){
  val[i]=func(i);
}

func()最快,最安全的版本是什么?这三个版本都完美无缺吗?

1 个答案:

答案 0 :(得分:0)

如果我们在函数内部声明一个静态变量(内联与否无关),编译器将生成一个具有唯一名称的全局变量(通常由函数名和变量名组合而成)。静态函数变量和全局变量之间的区别仅在于可见性范围。 所以版本2不是线程安全的。

让我们比较版本1和3.由于X是一个寄存器,版本1有点快,并且没有必要将它存储到主存储器中。速度差异不依赖于inlineopenmp,因此我将展示一个更简单的示例:

#include <math.h>

double func1(int i){
    double X;
    X=M_SQRT2*i;
    return X;
}

double func2(int i){
    static double X;
    X=M_SQRT2*i;
    return X;
}

编译:{{1​​}}

此处gcc -S -O3 test.c用于生成汇编程序文件-S,而test.s用于启用优化。

-O3

我们可能会发现func1: .LFB3: .cfi_startproc cvtsi2sd %edi, %xmm0 mulsd .LC0(%rip), %xmm0 ret .cfi_endproc func2: .LFB4: .cfi_startproc cvtsi2sd %edi, %xmm0 mulsd .LC0(%rip), %xmm0 movsd %xmm0, X.2782(%rip) ret .cfi_endproc 更长一行。 指令func2将结果存储到主存储器中。 movsd %xmm0, X.2782(%rip)是我们生成的全局变量。

因此版本1更好。