我正在检查使用
根据
在x86处理器上,编译器将对float类型的变量执行四舍五入,以适当的精度进行赋值、强制转换和传递参数给函数。这种舍入保证数据不会保留任何大于其类型容量的重要性。使用/ fp:precise编译的程序可能比未使用/ fp:precise编译的程序更慢、更大。 /fp:precise禁用了内置函数;而是使用标准运行时库例程。有关更多信息,请参见/Oi(生成内置函数)。
查看调用
从这个问题中,我相信现代的x86/x64处理器不使用80位寄存器(或者至少不鼓励使用),所以编译器会采用我认为是次优的方法,使用64位浮点数进行计算。由于内部函数被禁用,因此调用库函数sqrtf。
好的,很公平,这似乎符合文档所说的。
然而,当我编译x64架构时,出现了一些奇怪的情况:
计算不使用64位浮点数,而是使用指令集。据我所知,结果与使用
为什么存在这两者之间的差异?
现在,作为一项健全性检查,我在VS2010 x86中测试了相同的代码,并使用了
这里发生了什么?为什么VS2010使用内置函数而VS2012调用系统库?
针对x64平台测试VS2010的结果与VS2012类似(
我没有访问旧版VS的权限,因此无法在这些平台上进行任何测试。
供参考,我正在Windows 7 64位上进行测试,使用的是Intel i5-m430处理器。
/fp:precise
和/fp:fast
标志的代码。根据
/fp:precise
的MSDN文档:在x86处理器上,编译器将对float类型的变量执行四舍五入,以适当的精度进行赋值、强制转换和传递参数给函数。这种舍入保证数据不会保留任何大于其类型容量的重要性。使用/ fp:precise编译的程序可能比未使用/ fp:precise编译的程序更慢、更大。 /fp:precise禁用了内置函数;而是使用标准运行时库例程。有关更多信息,请参见/Oi(生成内置函数)。
查看调用
sqrtf
的反汇编(使用/arch:SSE2
,目标x86 / Win32
平台):0033185D cvtss2sd xmm0,xmm1
00331861 call __libm_sse2_sqrt_precise (0333370h)
00331866 cvtsd2ss xmm0,xmm0
从这个问题中,我相信现代的x86/x64处理器不使用80位寄存器(或者至少不鼓励使用),所以编译器会采用我认为是次优的方法,使用64位浮点数进行计算。由于内部函数被禁用,因此调用库函数sqrtf。
好的,很公平,这似乎符合文档所说的。
然而,当我编译x64架构时,出现了一些奇怪的情况:
000000013F2B199E movups xmm0,xmm1
000000013F2B19A1 sqrtps xmm1,xmm1
000000013F2B19A4 movups xmmword ptr [rcx+rax],xmm1
计算不使用64位浮点数,而是使用指令集。据我所知,结果与使用
/fp:fast
标志完全相同。为什么存在这两者之间的差异?
/fp:precise
在x64平台上不起作用吗?现在,作为一项健全性检查,我在VS2010 x86中测试了相同的代码,并使用了
/fp:precise
和/arch:SSE2
。令人惊讶的是,使用了sqrtpd
指令。00AF14C7 cvtps2pd xmm0,xmm0
00AF14CA sqrtsd xmm0,xmm0
00AF14CE cvtpd2ps xmm0,xmm0
这里发生了什么?为什么VS2010使用内置函数而VS2012调用系统库?
针对x64平台测试VS2010的结果与VS2012类似(
/fp:precise
似乎被忽略)。我没有访问旧版VS的权限,因此无法在这些平台上进行任何测试。
供参考,我正在Windows 7 64位上进行测试,使用的是Intel i5-m430处理器。
/fp:precise
有时会导致编译器自行将中间值提升到更高的精度,但这并不能解释这里的绝对不一致性。 - Mysticialprecise
、fast
和strict
。据我所知,precise
意味着编译器将尽可能生成精确的结果。(可能以性能为代价)fast
是不言自明的,与GCC的ffast-math
相同。strict
严格遵循IEEE标准。 - Mysticial