C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – SSE FP单元是否检测到0.0个操作数?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
根据我之前的 question,我的想法是在系数m_a,m_b为1.0或0.0时通过去除计算来优化算法.现在我尝试优化算法并得到一些我无法解释的奇怪结果.

一个分析仪运行100k样品.从文件(!)读取参数值:

b0 = 1.0 b1 = -1.480838022915731 b2 = 1.0

a0 = 1.0 a1 = -1.784147570544337 a2 = 0.854309980957510

第二个分析仪运行相同的100k样本.从文件(!)读取参数值:

b0 = 1.0 b1 = -1.480838022915731 b2 = 1.0

a0 = 1.0 a1 = -1.784147570544337 a2 = 0.0 <---只有a2不同! 在图中,左侧的数字(灰色背景)表示所需的cpu周期.因为参数a2 = 0.0的清晰可见的第二次运行要快得多. 我检查了调试和发布代码间的区别.发布代码更快(正如预期的那样).修改参数a2时,调试和释放代码有相同的奇怪行为. 然后我检查了ASM代码.我注意到使用了SSE指令.这是有效的,因为我用/ arch:SSE2编译.因此我禁用了SSE.生成代码不再使用SSE,性能不再依赖于参数值a2(如预期的那样) 因此,我得出的结论是,当使用SSE并且SSE引擎检测到a2为0.0时,它们是某种性能优势,因此省略了过时的乘法和减法.我从来没有听说过这个,并试图找到信息,但没有成功. 那么有人对我的表现结果有解释吗? 为完整起见,这是发布版本的相关ASM代码

00F43EC0  mov         edx,dword ptr [ebx]  
00F43EC2  movss       xmm0,dword ptr [eax+edi*4]  
00F43EC7  cmp         edx,dword ptr [ebx+4]  
00F43ECA  je          $LN419+193h (0F43F9Dh)  
00F43ED0  mov         esi,dword ptr [ebx+4]  
00F43ED3  lea         eax,[edx+68h]  
00F43ED6  lea         ecx,[eax-68h]  
00F43ED9  cvtps2pd    xmm0,xmm0  
00F43EDC  cmp         ecx,esi  
00F43EDE  je          $LN419+180h (0F43F8Ah)  
00F43EE4  movss       xmm1,dword ptr [eax+4]  
00F43EE9  mov         ecx,dword ptr [eax]  
00F43EEB  mov         edx,dword ptr [eax-24h]  
00F43EEE  movss       xmm3,dword ptr [edx+4]  
00F43EF3  cvtps2pd    xmm1,xmm1  
00F43EF6  mulsd       xmm1,xmm0  
00F43EFA  movss       xmm0,dword ptr [ecx]  
00F43EFE  cvtps2pd    xmm4,xmm0  
00F43F01  cvtps2pd    xmm3,xmm3  
00F43F04  mulsd       xmm3,xmm4  
00F43F08  xorps       xmm2,xmm2  
00F43F0B  cvtpd2ps    xmm2,xmm1  
00F43F0F  movss       xmm1,dword ptr [ecx+4]  
00F43F14  cvtps2pd    xmm4,xmm1  
00F43F17  cvtps2pd    xmm2,xmm2  
00F43F1A  subsd       xmm2,xmm3  
00F43F1E  movss       xmm3,dword ptr [edx+8]  
00F43F23  mov         edx,dword ptr [eax-48h]  
00F43F26  cvtps2pd    xmm3,xmm3  
00F43F29  mulsd       xmm3,xmm4  
00F43F2D  subsd       xmm2,xmm3  
00F43F31  movss       xmm3,dword ptr [edx+4]  
00F43F36  cvtps2pd    xmm4,xmm0  
00F43F39  cvtps2pd    xmm3,xmm3  
00F43F3C  mulsd       xmm3,xmm4  
00F43F40  movss       xmm4,dword ptr [edx]  
00F43F44  cvtps2pd    xmm4,xmm4  
00F43F47  cvtpd2ps    xmm2,xmm2  
00F43F4B  xorps       xmm5,xmm5  
00F43F4E  cvtss2sd    xmm5,xmm2  
00F43F52  mulsd       xmm4,xmm5  
00F43F56  addsd       xmm3,xmm4  
00F43F5A  movss       xmm4,dword ptr [edx+8]  
00F43F5F  cvtps2pd    xmm1,xmm1  
00F43F62  movss       dword ptr [ecx+4],xmm0  
00F43F67  mov         edx,dword ptr [eax]  
00F43F69  cvtps2pd    xmm4,xmm4  
00F43F6C  mulsd       xmm4,xmm1  
00F43F70  addsd       xmm3,xmm4  
00F43F74  xorps       xmm1,xmm1  
00F43F77  cvtpd2ps    xmm1,xmm3  
00F43F7B  movss       dword ptr [edx],xmm2  
00F43F7F  movaps      xmm0,xmm1  
00F43F82  add         eax,70h  
00F43F85  jmp         $LN419+0CCh (0F43ED6h)  
00F43F8A  movss       xmm1,dword ptr [ebx+10h]  
00F43F8F  cvtps2pd    xmm1,xmm1  
00F43F92  mulsd       xmm1,xmm0  
00F43F96  xorps       xmm0,xmm0  
00F43F99  cvtpd2ps    xmm0,xmm1  
00F43F9D  mov         eax,dword ptr [ebp-4Ch]  
00F43FA0  movss       dword ptr [eax+edi*4],xmm0  
00F43FA5  mov         ecx,dword ptr [ebp-38h]  
00F43FA8  mov         eax,dword ptr [ebp-3Ch]  
00F43FAB  sub         ecx,eax  
00F43FAD  inc         edi  
00F43FAE  sar         ecx,2  
00F43FB1  cmp         edi,ecx  
00F43FB3  jb          $LN419+0B6h (0F43EC0h)

编辑:按发布代码替换调试ASM代码.

解决方法

SSE上的FP乘法没有早期出局.这是一个完全流水线操作,延迟时间短,因此增加早期输出会使指令退出变得复杂,同时提供零性能优势.在现代处理器上通常具有数据相关执行特性的唯一指令是除法和平方根(忽略次正规,这会影响更广泛的指令).英特尔和AMD都广泛记录了这一点,Agner Fog也独立记录了这一点.

那么为什么你会看到性能的变化呢?最可能的解释是由于输入或结果不正常而遇到失速;这与DSP滤波器和延迟非常相似,就像你拥有的那样.如果没有看到你的代码和输入数据,就不可能确定这是发生了什么,但它是迄今为止最可能的解释.如果是这样,您可以通过在MXCSR中设置DAZ和FTZ位来解决问题.

英特尔文档:
http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf(请参阅附录中的延迟表,注意mulss和mulsd有固定值.)

AMD 16h指令延迟(excel电子表格):
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/AMD64_16h_InstrLatency_1.1.xlsx

Agner Fog的Intel和AMD指令延迟表:
http://www.agner.org/optimize/instruction_tables.pdf

大佬总结

以上是大佬教程为你收集整理的c – SSE FP单元是否检测到0.0个操作数?全部内容,希望文章能够帮你解决c – SSE FP单元是否检测到0.0个操作数?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。