开发者

How do you get the ICC compiler to generate SSE instructions within an inner loop?

I have an inner loop such as this

for(i=0 ;i<n;i++){
 x[0] += A[i] * z[0];
 x[1] += A[i] * z[1];
 x[2] += A[i] * 开发者_StackOverflow社区z[2];
 x[3] += A[i] * z[3];
}

The inner 4 instructions can be easily converted to SSE instructions by a compiler. Do current compilers do this ? If they do what do I have to do to force this on the compiler?


From what you've provided, this can't be vectorized, because the pointers could alias each other, i.e. the x array could overlap with A or z.

A simple way to help the compiler out would be to declare x as __restrict. Another way would be to rewrite it like so:

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;
}

I've never actually tried to get a compiler to auto-vectorize code, so I don't know if that will do it or not. Even if it doesn't get vectorized, it should be faster since the loads and stores can be ordered more efficiently and without causing a load-hit-store.

If you have more information than the compiler does, (e.g. whether or not your pointers are 16-byte aligned), and should be able to use that to your advantage (e.g. using aligned loads). Note that I'm not saying you should always try to beat the compiler, only when you know more than it does.

Further reading:

  • Load-hit-stores and the __restrict keyword
  • Memory Optimization (aliasing starts around slide 35)


ICC auto-vectorizes the below code snippet for SSE2 by default:

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;
}

By using restrict keyword, the memory aliasing assumption is ignored. The vectorization report generated is:

$ 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

To confirm if SSE instructions are generated, open the ASM generated (test.s) and you will find the following instructions:

..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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜