我正在尝试在称为数千次循环的循环中优化指令块,这是我算法的瓶颈。

此代码块计算N个矩阵3x3(iA数组)与N个 vector 3(iV数组)的乘积,并将N个结果存储在oV数组中。 (N不是固定值,通常在3000到15000之间)

每行矩阵和 vector 都是128位对齐的(4个浮点数)以利用SSE优化(忽略第4个浮点值)。

C++代码:

  __m128* ip = (__m128*)iV;
  __m128* op = (__m128*)oV;
  __m128* A = (__m128*)iA;

  __m128 res1, res2, res3;
  int i;

  for (i=0; i<N; i++)
  {
    res1 = _mm_dp_ps(*A++, *ip, 0x71);
    res2 = _mm_dp_ps(*A++, *ip, 0x72);
    res3 = _mm_dp_ps(*A++, *ip++, 0x74);

    *op++ = _mm_or_ps(res1, _mm_or_ps(res2, res3));
  }

编译器生成以下指令:
000007FEE7DD4FE0  movaps      xmm2,xmmword ptr [rsi]               //move "ip" in register
000007FEE7DD4FE3  movaps      xmm1,xmmword ptr [rdi+10h]           //move second line of A in register
000007FEE7DD4FE7  movaps      xmm0,xmmword ptr [rdi+20h]           //move third line of A in register
000007FEE7DD4FEB  inc         r11d                                 //i++
000007FEE7DD4FEE  add         rbp,10h                              //op++
000007FEE7DD4FF2  add         rsi,10h                              //ip++
000007FEE7DD4FF6  dpps        xmm0,xmm2,74h                        //dot product of 3rd line of A against ip
000007FEE7DD4FFC  dpps        xmm1,xmm2,72h                        //dot product of 2nd line of A against ip
000007FEE7DD5002  orps        xmm0,xmm1                            //"merge" of the result of the two dot products
000007FEE7DD5005  movaps      xmm3,xmmword ptr [rdi]               //move first line of A in register
000007FEE7DD5008  add         rdi,30h                              //A+=3
000007FEE7DD500C  dpps        xmm3,xmm2,71h                        //dot product of 1st line of A against ip
000007FEE7DD5012  orps        xmm0,xmm3                            //"merge" of the result
000007FEE7DD5015  movaps      xmmword ptr [rbp-10h],xmm0           //move result in memory (op)
000007FEE7DD5019  cmp         r11d,dword ptr [rbx+28h]             //compare i
000007FEE7DD501D  jl          MyFunction+370h (7FEE7DD4FE0h)       //loop

我对底层优化不是很熟悉,所以问题是:如果我自己编写汇编代码,您是否看到一些可能的优化?

例如,如果我进行更改,它将运行得更快吗:
add         rbp,10h
movaps      xmmword ptr [rbp-10h],xmm0

通过
movaps      xmmword ptr [rbp],xmm0
add         rbp,10h

我还读到ADD指令比INC更快...

最佳答案

计算带偏移量的间接地址(例如rbp-10)非常便宜,因为“有效地址计算”单元中存在用于此类计算的特殊硬件[我认为名称不同,但是想不到或没有成功与谷歌找到它的名字]。

但是,add rbp,10h[rbp-10h]之间存在依赖关系,这可能会引起问题-但在这种特殊情况下,我对此表示怀疑。在您的情况下,rbp-10与使用它之间有很长的距离,因此这不是问题。编译器可能把它放的太远了,因为此时它是“免费的”,因为处理器将等待数据从外部进入先前已读取的xmm寄存器。换句话说,我们可以在循环开始时停留在xmm0xmm1xmm2的读取之间的任何工作,以及使用dppsxmm0xmm1xmm2指令都是有益的,因为处理器将等待该数据“到达”,然后才能计算dpps结果。

07-24 09:45
查看更多