【问题标题】:How do you get the ICC compiler to generate SSE instructions within an inner loop?如何让 ICC 编译器在内循环中生成 SSE 指令?
【发布时间】:2011-07-06 03:36:47
【问题描述】:

我有一个像这样的内部循环

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 指令。当前的编译器会这样做吗?如果他们做了我必须做些什么来强制编译器这样做?

【问题讨论】:

    标签: sse simd vectorization icc


    【解决方案1】:

    根据您提供的内容,这无法向量化,因为指针可能会相互别名,即 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 字节对齐的),并且应该能够利用它来发挥您的优势(例如,使用对齐的负载)。请注意,我并不是说你应该总是试图打败编译器,只有当你知道的比它多的时候。

    进一步阅读:

    【讨论】:

      【解决方案2】:

      ICC 默认为 SSE2 自动矢量化以下代码 sn-p:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-06
        • 2016-11-18
        • 2017-09-15
        • 1970-01-01
        相关资源
        最近更新 更多