什么决定了x87 FPU控制字的默认设置 - 特别是精确控制字段?编译器是否根据目标处理器进行设置?是否有编译器选项来更改它?
在Intel Core Duo处理器上使用Microsoft Visual C ++ 2008 Express Edition,精确控制字段的默认设置为“01b”,表示精度为双(53位)。我想知道 - 为什么默认值不是“11”b或扩展(64位)精度?
(我知道我可以使用_controlfp更改它。)
答案 0 :(得分:2)
Microsoft C运行时DLL(MSVCRT.DLL)中存在一个错误,它会更改FPCW,这可能会根据DLL加载的顺序更改应用程序行为。
因此,如果您关心FPCW设置,最好不要在执行前将其更改为所需的设置(即使在函数调用边界上),也可以在完成后将其更改回来。 (如果你打电话给任何功能或图书馆,请注意那些可能会改变它的人,并且不要那么体贴到为你改变它!)
另请注意:FPCW修改起来很昂贵,但检查起来并不是很昂贵。因此,如果很有可能它已经按照您想要的方式设置,您可以在修改之前通过检查来节省大量时间。
答案 1 :(得分:0)
从理论的角度来看:可能是使用它的最后一件事,或者除非英特尔认为这是一个很好的默认值。
从实际角度来看:在开始工作之前,只需将其设置为所需的精度即可。显式默认值通常优于默认默认值。
答案 2 :(得分:0)
当操作系统设置进程(或线程)时 - 例如,当程序启动时,它负责将控制寄存器初始化为默认状态(具体的默认状态可能因平台而异) 。它还负责保存和恢复上下文切换的状态,这样您的程序就不会将状态放到同样在系统上运行的其他进程中。
除此之外,编译器或语言运行库可能会在代码执行之前修改状态。
所以要么:Windows的默认FP状态是53位精度,或者VS2008默认插入代码将处理器设置为53位精度。 Windows默认进程状态应记录在该平台的ABI文档中。
答案 3 :(得分:0)
我一直在想同样的原始问题。我已经尝试过VC ++ 6& Windows 2000(32位)上的MinGW。
一个简单的3行程序将FPU控制字设置为VC ++的“双精度”(0x027f)和使用MinGW(0x037f)编译时的“扩展精度”。 在同一台机器上,gcc / Linux-32具有相同的扩展精度(0x37f)。 即MinGW和gcc / Linux似乎具有相同的FPU设置。