标量积在循环中的自动向量化

时间:2018-08-01 14:54:47

标签: c++ openmp intel auto-vectorization

我正在尝试自动向量化以下循环。接下来,我们在矩阵的下三角形上使用i-j-循环。不幸的是,矢量化报告无法对j循环和k循环进行矢量化(=转换为AVX SIMD指令)。但是我认为这很简单,因为没有指针别名(#pragma ivdep和编译器选项-D NOALIAS)并且数据(x:1D数组和p:1D数组)对齐为64个字节。

if语句可能是一个问题,但是即使使用了无if的解决方案(昂贵的移位操作和双倍符号计数),编译器也无法向量化此循环。

__assume_aligned(x, 64);
__assume_aligned(p, 64);
#pragma omp parallel for simd reduction(+:accum)
for ( int i = 1 ; i < N ; i++ ){ // loop over lower triangle (i,j), OpenMP SIMD LOOP WAS VECTORIZED
    for ( int j = 0 ; j < i ; j++ ){ // <-- remark #25460: No loop optimizations reported
        double __attribute__((aligned(64))) scalarp = 0.0;
        #pragma omp simd
        for ( int k=0 ; k < D ; k++ ){ // <-- remark #25460: No loop optimizations reported
            // scalar product of \sum_k x_{i,k} \cdot x_{j,k}
            scalarp += x[i*D + k] * x[j*D + k];
        }

        // Alternative to following if:
        // accum +=  - ( (long long) floor( - ( scalarp + p[i] + p[j] ) ) >> 63);
        #pragma ivdep
        if ( scalarp + p[i] + p[j] >= 0 ){ // check if condition is satisfied
            accum += 1;
        }
    }
}

是否涉及到问题,直到运行时才知道每个OpenMP线程的OpenMP起点?我认为这可以解决simd子句,而Intel的自动向量化功能已意识到这一点。

Intel编译器:18.0.2 20180210

编辑:我已经研究了程序集,现在很明显,代码已经被矢量化了,很抱歉给大家带来麻烦。

1 个答案:

答案 0 :(得分:1)

查看程序集确实有帮助。代码已经向量化。在这种特殊情况下,OpenMP SIMD LOOP WAS VECTORIZED还负责内部循环。