c - openmp、内联函数和静态变量(纯 C)

标签 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 block 内调用 func() 函数,例如:

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

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

最佳答案

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

让我们比较一下版本 1 和 3。版本 1 的速度要快一些,因为 X 是一个寄存器,并且不需要将其存储到主存中。速度差异不取决于 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;
}

编译: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)将结果存储到主存。 X.2782 是我们生成的全局变量。

所以版本 1 更好。

关于c - openmp、内联函数和静态变量(纯 C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39327541/

相关文章:

c++ - U后缀的含义

c++ - OpenMP 指针

c++ - 删除多余的并行语句时的不同程序行为

c - OpenMP 任务的递归阶乘行为?

C strcmp() 没有按预期返回 0

c - 如何在C中找到文件指针的当前行位置?

c - 结束应用程序的 Xcode 信号

c - 如何返回仅包含偶数/奇数的数组并删除不必要的单元格?

c++ - OpenMP 是否复制私有(private)对象?

c++ - 采样条件分布OpenMP