如何使用SSE指令提高FIR算法效率(进化二)

rel="File-List" href="file:///C:/DOCUME%7E1/MICROS%7E1/LOCALS%7E1/Temp/msoclip1/01/clip_filelist.xml">

如何使用SSE指令提高FIR算法效率(进化二)

在“如何使用SSE指令提高FIR算法效率(进化一)“一文中,我们通过SHUFPS指令来完成行列向量之间的转化,实现了向量相加一次写操作的功能,很大程度的提高了程序的执行效率。

那么参考SSE/SEE2的指令,我们能否用其他方式来完成呢?

,好像有,再想想

哦,对了,MOVLHPS,MOVLHPS不是也可以吗?那么让我们看看如何实现吧J

为了是大家能够看的清楚一些,代码中加入了部分的注释(很抱歉,在相关的前两篇文章中,我没有做这个方面的工作:-(,以后一定要加强)

还是在看代码之前,先回顾一下问题:

我们要把A3+A2+A1+A0的值放入数组out[ 0 ]中,B3+B2+B1+B0的值放入out[ 1 ]中,依次类推直到out[ 3 ] = D3+D2+D1+D0。程序的前半段已经将它们存储到

xmm0=[A3, A2, A1, A0]

xmm1=[B3, B2, B1, B0]

xmm2=[C3, C2, C1, C0]

xmm3=[D3, D2, D1, D0]

因为它们是行相加而非是列相加,所以没有合适的SSE/SSE2指令直接使用。程序的下半段利用MOVLHPS,MOVHLPSSHUFPS的组合实现了转换和向量相加,并存储于out数组中。

static void ShowFIR_O4( float *inPtr, float *outPtr, float *coeffPtr, unsigned int count )

{

       __asm

       {

              xorps xmm0, xmm0

              xorps xmm1, xmm1

              xorps xmm2, xmm2

              xorps xmm3, xmm3

              xor eax, eax

              xor ecx, ecx

              mov ebx, DWORD PTR[ coeffPtr ]

              mov esi, DWORD PTR[ inPtr ]

              mov edx, DWORD PTR[ outPtr ]

              jmp b2

b1:

              movaps xmm4, XMMWORD PTR[ ebx + ecx * 4 ]

 

              movaps xmm5, XMMWORD PTR[ esi + ecx * 4 ]

              mulps xmm5, xmm4

              addps xmm0, xmm5

 

              movups xmm5, XMMWORD PTR[ esi + ecx * 4 + 4 ]

              mulps xmm5, xmm4

              addps xmm1, xmm5

 

              movups xmm5, XMMWORD PTR[ esi + ecx * 4 + 8 ]

              mulps xmm5, xmm4

              addps xmm2, xmm5

 

              movups xmm5, XMMWORD PTR[ esi + ecx * 4 + 12 ]

              mulps xmm5, xmm4

              addps xmm3, xmm5

             

              add ecx, 4

              cmp ecx, TAP

              jb b1

 

              // xmm0: A3, A2, A1, A0

              // xmm1: B3, B2, B1, B0

              // xmm2: C3, C2, C1, C0

              // xmm0: D3, D2, D1, D0

              movaps xmm4, xmm0          // xmm4: A3, A2, A1, A0

              movlhps xmm4, xmm1         // xmm4: B1, B0, A1, A0

              movaps xmm5, xmm1          // xmm5: B3, B2, B1, B0

              movhlps xmm5, xmm0         // xmm5: B3, B2, A3, A2

              addps xmm4, xmm5             // xmm4: B1+B3, B0+B2, A1+A3, A0+A2

 

              movaps xmm6, xmm2          // xmm6: C3, C2, C1, C0

              movlhps xmm6, xmm3         // xmm6: D1, D0, C1, C0

              movaps xmm7, xmm3          // xmm7: D3, D2, D1, D0

              movhlps xmm7, xmm2         // xmm7: D3, B2, C3, C2

              addps xmm6, xmm7             // xmm6: D1+D3, D0+D2, C1+C3, C0+C2

 

              movaps xmm5, xmm4          // xmm5: B1+B3, B0+B2, A1+A3, A0+A2

              shufps xmm4, xmm6, 0x88   // xxm4: D0+D2, C0+C2, B0+B2, A0+A2

              shufps xmm6, xmm5, 0xDD // xmm6: D1+D3, C1+C3, B1+B3, A1+A3

              addps xmm4, xmm6             // xMM4: D0+D1+D2+D3, C0+C1+C2+C3, B0+B1+B2+B3, A0+A1+A2+A3

 

              movaps XMMWORD PTR[ edx + eax * 4 ], xmm4

 

              add eax, 4

b2:

              cmp eax, count - TAP

              jb b1

       }

}

 

相比于ShowFIR_O3中的相关部分,这里的指令数明显少了很多(ShowFIR_O415条指令,ShowFIR_O331条指令),大概为其的一半。

 

那么我们是否会认为它的速度要快很多呢?

也许吧?!从理论上说,指令少总是要快一些的,但是ShowFIR_O4使用的MOVHLPS,MOVLHPS是数据相关的指令,它可能会受到这个方面的影响。不过,所有的猜想总没有测试来的直接。

请看下面数据:

Intel Pentium-M2.2G上运行10000次后的计数值

4: ShowFIR_O3 delta = 1475

5: ShowFIR_O4 delta = 1476

 

AMD Anthlon 4600+上运行10000次后的计数值:

4: ShowFIR_O3 delta = (783, 0)

5: ShowFIR_O4 delta = (799, 0)

 

从结果看,两者的性能差不多(个人观点,它们的结果会因为CPU框架不同产生一些或快或慢的结果,但是差别不会太大。)。ShowFIR_O3中的操作没有进行优化,如果在稍慢的情况下,能够通过再次优化来提速。

 

小结

1. 本文主要目的是提供一个实现方法来开阔思路,在实现的同时也能够回顾和进一步熟练使用SSE/SSE2指令。

2. 它与ShowFIR_O3中的相关代码段可以作为一个模板供日后参考使用。

 

总之,它是对以前一篇学习笔记的再探讨,所有的东西并不是最佳答案,它将会在日后的学习中逐步完善。正如以前一贯的作风,希望网友们能够给我多找出一些岔子,以便我再学习再提高。谢谢了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值