带有循环迭代器和 omp simd 的私有子句

private clause with loop iterators and omp simd

当我尝试这个时

#pragma omp simd private(i)
for(i=0; i<n; i++)

使用 GCC 5.2.1 时出现错误

error: iteration variable ‘i’ should not be private

我对 firstprivatelastprivate 也有同样的错误。我从这段代码中发现了这一点

int i;
#pragma omp parallel for simd reduction(+:sum) lastprivate(i)
for(i=0; i<(n/8)*8; i++) sum += a[i];
for(; i<n; i++) sum += a[i];

然而,这工作正常

int i,j;
#pragma omp parallel for simd reduction(+:sum) lastprivate(j)
for(i=0; i<(n/8)*8; i++) {sum += a[i]; j=i;}
for(; j<n; j++) sum += a[j];

但这似乎是一个愚蠢的 hack。

GCC 也给我警告

warning: ‘i’ may be used uninitialized in this function

with parallel for simd 但仅使用 parallel for.

时没有警告

为什么我不能用 omp simdomp for simd 将并行循环迭代器显式声明为 private?反正不是隐含的private吗?


来自 Hristo Iliev 的回答中推荐的 OpenMP 4.0 规范第 14.1.2 节。

The loop iteration variable in the associated for-loop of a simd construct with just one associated for-loop may be listed in a linear clause with a constant-linear-step that is the increment of the associated for-loop.

The loop iteration variables in the associated for-loops of a simd construct with multiple associated for-loops may be listed in a lastprivate clause.

这个有效

int i;
#pragma omp parallel for simd reduction(+:sum) linear(i)
for(i=0; i<(n/8)*8; i++) sum += a[i];
for(; i<n; i++) sum += a[i];

但似乎也不需要 linear(i) 所以迭代器默认为 linear(i).

所以我本来可以做到的

 #pragma omp parallel for simd reduction(+:sum)

看来迭代器默认有效 lastprivate omp simdomp for simd.

我仍然收到警告

‘i’ may be used uninitialized in this function

我应该选择第 14.1.1 节

Certain variables and objects have predetermined data-sharing attributes as follows:

The loop iteration variable in the associated for-loop of a simd construct with just one associated for-loop is linear with a constant-linear-step that is the increment of the associated for-loop.


这是一个工作示例,它给出带有 -fopenmp 的警告,但没有 -fopenmp

则没有警告
‘i’ may be used uninitialized in this function

代码

#include <stdio.h>
//#define N 101                                                                                                       
float foo(float *a, int n)
{
    float sum = 0;
    int i;
    #pragma omp parallel for simd reduction(+:sum)
    for(i=0; i<(n/8)*8; i++) sum += a[i];
    for(; i<n; i++) sum += a[i];
    return sum;
}

int main(void) {
    const int N = 101;
    float a[N]; for(int i=0; i<N; i++) a[i] = i;
    printf("%f\n", foo(a,N));
}

不,simd 构造中的循环迭代变量具有单个关联的 for 循环具有预定的数据共享 class linear 而不是 privateOpenMP 4.0, §2.14.1.1). linear 提供的功能是 private 的超集,因此将 i 声明为 (last)private 是降级,因此会出现错误。