我正在检查一些使用/fp:precise
和/fp:fast
标记的代码。
根据/fp:precise
的{{3}}:
使用/ fp:精确地在x86处理器上,编译器将对float类型的变量执行舍入,以便为赋值和强制转换以及将参数传递给函数时具有适当的精度。这种舍入保证了数据不会保留大于其类型容量的任何重要性。使用/ fp:precise编译的程序可以比没有/ fp:precise编译的程序更慢更大。 / fp:exact禁用内在函数;而是使用标准的运行时库例程。有关更多信息,请参阅/ Oi(生成内部函数)。
查看对sqrtf
的调用的反汇编(使用/arch:SSE2
调用,定位x86/Win32
平台):
0033185D cvtss2sd xmm0,xmm1
00331861 call __libm_sse2_sqrt_precise (0333370h)
00331866 cvtsd2ss xmm0,xmm0
来自MSDN documentation我相信现代的x86 / x64处理器不使用80位寄存器(或者至少不鼓励使用它们),所以编译器做了我认为是下一个最好的事情,并用64位双打。因为内在函数被禁用,所以调用了一个库sqrtf函数。
好的,相当公平,这似乎符合文档所说的内容。
然而,当我为x64 arch编译时,会发生一些奇怪的事情:
000000013F2B199E movups xmm0,xmm1
000000013F2B19A1 sqrtps xmm1,xmm1
000000013F2B19A4 movups xmmword ptr [rcx+rax],xmm1
不使用64位双精度执行计算,并且正在使用内在函数。据我所知,结果与使用/fp:fast
标志的结果完全相同。
为什么两者之间存在差异? /fp:precise
根本不适用于x64平台吗?
现在,作为一项完整性检查,我使用/fp:precise
和/arch:SSE2
在VS2010 x86中测试了相同的代码。令人惊讶的是,正在使用sqrtpd
内在函数!
00AF14C7 cvtps2pd xmm0,xmm0
00AF14CA sqrtsd xmm0,xmm0
00AF14CE cvtpd2ps xmm0,xmm0
这里发生了什么?为什么VS2010在VS2012调用系统库时使用内在函数?
针对x64平台测试VS2010的结果与VS2012类似(/fp:precise
似乎被忽略)。
我无法访问任何旧版本的VS,因此我无法在这些平台上进行任何测试。
作为参考,我正在使用Intel i5-m430处理器在Windows 7 64位中进行测试。
答案 0 :(得分:3)
首先,你应该阅读关于中间浮点精度的this非常好的博文。这篇文章只处理visual studio生成的代码(但这就是你的问题所在)。现在举例来说:
0033185D cvtss2sd xmm0,xmm1
00331861 call __libm_sse2_sqrt_precise (0333370h)
00331866 cvtsd2ss xmm0,xmm0
此汇编代码已使用/fp:precise /arch:SSE2
为x86平台生成。根据{{3}},精确浮点模型可以促进所有计算在x86平台上内部加强 。它还可以防止使用内在函数(我认为你已经阅读了documentation)。因此,代码以从float到double的转换开始,然后是双精度sqrt调用,最后将结果转换回float。
000000013F2B199E movups xmm0,xmm1
000000013F2B19A1 sqrtps xmm1,xmm1
000000013F2B19A4 movups xmmword ptr [rcx+rax],xmm1
第二个示例是针对x64(amd64)平台编译的,这个平台的行为完全不同!根据文件:
出于性能原因,中间运算是以任一操作数的最宽精度计算的,而不是以最宽的精度计算。
因此,计算将在内部以单精度完成。我认为他们也决定尽可能使用内在函数,因此/fp:precise
和/fp:fast
之间的差异在x64平台上稍微 。新行为导致更快的代码和它使程序员能够更好地控制究竟发生了什么(他们能够改变游戏规则,因为兼容性问题与新的x64平台无关)。遗憾的是,这些更改/差异未在文档中明确说明。
00AF14C7 cvtps2pd xmm0,xmm0
00AF14CA sqrtsd xmm0,xmm0
00AF14CE cvtpd2ps xmm0,xmm0
最后,最后一个示例是使用Visual Studio 2010编译器编译的,我认为他们不应该使用sqrt的内在函数,因为他们最好不要(至少在/fp:precise
模式下),但他们决定改变/再次在Visual Studio 2012中修复此行为(请参阅this information)。