如何让ICC编译器在内部循环中生成SSE指令?

时间:2011-07-06 03:36:47

标签: sse simd vectorization icc

我有一个内循环,比如这个

for(i=0 ;i<n;i++){
 x[0] += A[i] * z[0];
 x[1] += A[i] * z[1];
 x[2] += A[i] * z[2];
 x[3] += A[i] * z[3];
}

内部4条指令可以由编译器轻松转换为SSE指令。当前的编译器会这样做吗?如果他们做了我必须做的事情来强制执行编译器?

2 个答案:

答案 0 :(得分:4)

根据您提供的内容,无法对其进行矢量化,因为指针可以互为别名,即x数组可能与Az重叠。

帮助编译器的一种简单方法是将x声明为__restrict。另一种方法是像这样重写它:

for(i=0 ;i<n;i++)
{
 float Ai=A[i];
 float z0=z[0], z1=z[1], z2=z[2], z3=z[3];
 x[0] += Ai * z0;
 x[1] += Ai * z1;
 x[2] += Ai * z2;
 x[3] += Ai * z3;
}

我从来没有真正试图让编译器自动向量化代码,所以我不知道是否会这样做。即使它没有被矢量化,它也应该更快,因为可以更有效地订购加载和存储,而不会导致加载命中存储。

如果您有比编译器更多的信息,(例如,您的指针是否为16字节对齐),并且应该能够使用它(例如使用对齐的加载)。请注意,我并不是说你应该总是试图击败编译器,只有当你知道的比它更多的时候。

进一步阅读:

答案 1 :(得分:0)

默认情况下,ICC会为SSE2自动矢量化以下代码段:

void foo(float *__restrict__ x, float *__restrict__ A, float *__restrict__ z, int n){
for(int i=0;i<n;i++){
 x[0] += A[i] * z[0];
 x[1] += A[i] * z[1];
 x[2] += A[i] * z[2];
 x[3] += A[i] * z[3];
}
return;
}

通过使用 restrict 关键字,将忽略内存别名假设。生成的矢量化报告是:

$ icpc test.cc -c -vec-report2 -S
test.cc(2): (col. 1) remark: PERMUTED LOOP WAS VECTORIZED
test.cc(3): (col. 2) remark: loop was not vectorized: not inner loop

要确认是否生成了SSE指令,请打开生成的ASM(test.s),您将找到以下说明:

..B1.13:                        # Preds ..B1.13 ..B1.12
        movaps    (%rsi,%r15,4), %xmm10                         #3.10
        movaps    16(%rsi,%r15,4), %xmm11                       #3.10
        mulps     %xmm0, %xmm10                                 #3.17
        mulps     %xmm0, %xmm11                                 #3.17
        addps     %xmm10, %xmm9                                 #3.2
        addps     %xmm11, %xmm6                                 #3.2
        movaps    32(%rsi,%r15,4), %xmm12                       #3.10
        movaps    48(%rsi,%r15,4), %xmm13                       #3.10
        movaps    64(%rsi,%r15,4), %xmm14                       #3.10
        movaps    80(%rsi,%r15,4), %xmm15                       #3.10
        movaps    96(%rsi,%r15,4), %xmm10                       #3.10
        movaps    112(%rsi,%r15,4), %xmm11                      #3.10
        addq      $32, %r15                                     #2.1
        mulps     %xmm0, %xmm12                                 #3.17
        cmpq      %r13, %r15                                    #2.1
        mulps     %xmm0, %xmm13                                 #3.17
        mulps     %xmm0, %xmm14                                 #3.17
        addps     %xmm12, %xmm5                                 #3.2
        mulps     %xmm0, %xmm15                                 #3.17
        addps     %xmm13, %xmm4                                 #3.2
        mulps     %xmm0, %xmm10                                 #3.17
        addps     %xmm14, %xmm7                                 #3.2
        mulps     %xmm0, %xmm11                                 #3.17
        addps     %xmm15, %xmm3                                 #3.2
        addps     %xmm10, %xmm2                                 #3.2
        addps     %xmm11, %xmm1                                 #3.2
        jb        ..B1.13       # Prob 75%                      #2.1
                                # LOE rax rdx rsi r8 r9 r10 r13 r15 ecx ebp edi r11d r14d bl xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9
..B1.14:                        # Preds ..B1.13
        addps     %xmm6, %xmm9                                  #3.2
        addps     %xmm4, %xmm5                                  #3.2
        addps     %xmm3, %xmm7                                  #3.2
        addps     %xmm1, %xmm2                                  #3.2
        addps     %xmm5, %xmm9                                  #3.2
        addps     %xmm2, %xmm7                                  #3.2
        lea       1(%r14), %r12d                                #2.1
        cmpl      %r12d, %ecx                                   #2.1
        addps     %xmm7, %xmm9                                  #3.2
        jb        ..B1.25       # Prob 50%                      #2.1
相关问题