x87 FPU 控制字的默认设置由什么决定?
是什么决定了 x87 FPU 控制字的默认设置——具体来说,精度控制字段?编译器是否根据目标处理器进行设置?是否有编译器选项可以更改它?
在 Intel Core Duo 处理器上使用 Microsoft Visual C++ 2008 Express Edition,精度控制字段的默认设置为“01b”,表示双精度(53 位)。我想知道 - 为什么默认值不是“11”b 或扩展(64 位)精度?
(我知道我可以使用 _controlfp 更改它。)
What determines the default setting of the x87 FPU control word -- specifically, the precision control field? Does the compiler set it based on the target processor? Is there a compiler option to change it?
Using Microsoft Visual C++ 2008 Express Edition on an Intel Core Duo processor, the default setting for the precision control field is "01b", meaning double (53 bit) precision. I'm wondering -- why is the default not "11"b, or extended (64 bit) precision?
(I know I can change it using _controlfp.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Microsoft C 运行时 DLL (MSVCRT.DLL) 中存在一个错误,它会更改 FPCW,这可能会根据 DLL 加载的顺序更改应用程序行为。
因此,如果您关心 FPCW 设置,最佳实践不仅是在执行之前将其更改为所需的设置(即使在函数调用边界上),而且在完成后将其更改回来。 (如果您调用任何函数或库,请小心被调用者,他们可能会更改它,但不会考虑到为您将其更改回来!)
还要注意:修改 FPCW 的成本很高,但检查的成本却不是很高。因此,如果它很可能已经按照您想要的方式设置,您可以通过在修改之前进行检查来节省大量时间。
There was a bug in the Microsoft C runtime DLL (MSVCRT.DLL) where it would change the FPCW, which could change application behavior depending on the order of DLL loading.
So if you care about the FPCW setting, it is not only best practice to change it to your desired settings before execution, (even on a function call boundary), but also to change it back when you are done. (And if you call any functions or libaries, beware of callees who might change it and not be so considerate as to change it back for you!)
Also note: the FPCW is expensive to modify, but not very expensive to examine. So if there's a good chance it is already set the way you want, you can save a lot of time by checking it before modifying it.
从理论的角度来看:可能是最后一个使用它的东西,或者除非如此,无论英特尔决定什么都将是一个很好的默认值。
从实用的角度来看:只需在开始工作之前将其设置为您想要的精度即可。显式默认值通常比隐含默认值更好。
From a theoretical standpoint: probably the last thing that used it, or barring that, whatever Intel decided would be a good default.
From a practical standpoint: just set it to your desired precision before you begin work. Explicit defaults are usually better than implied defaults.
当操作系统设置进程(或线程)时 - 例如,当程序启动时,它负责将控制寄存器初始化为默认状态(默认状态的具体情况可能因平台而异)。它还负责保存和恢复上下文切换周围的状态,以便您的程序不会将状态渗透到也在系统上运行的其他进程中。
除此之外,编译器或语言运行时可能会在执行代码之前修改状态。
因此,要么:Windows 的默认 FP 状态是 53 位精度,要么 VS2008 插入代码将处理器默认设置为 53 位精度。 Windows 默认进程状态应记录在平台的 ABI 文档中。
When the OS sets up a process (or thread) -- say, when your program launches, it is responsible for initializing the control registers to the default state (exactly what the default state is can vary somewhat from platform to platform). It is also responsible for saving and restoring state around context switches, so that your program doesn't bleed state into some other process that is also running on the system.
Beyond that, a compiler or a language runtime might modify the state before your code is executed.
So either: Windows' default FP state is 53 bit precision or VS2008 inserts code to set the processor to 53 bit precision by default. The Windows default process state should be documented in the ABI documentation for the platform.
我一直想知道同样的原始问题。我已经尝试过 VC++ 6 & Windows 2000(32 位)上的 MinGW。
一个简单的 3 行程序的 FPU 控制字在 VC++ 中设置为“双精度”(0x027f),在使用 MinGW (0x037f) 编译时设置为“扩展精度”。
在同一台机器上,gcc/Linux-32 具有相同的扩展精度 (0x37f)。
即 MinGW 和 gcc/Linux 似乎具有相同的 FPU 设置。
I've been wondering about the same original question. I've experimented with VC++ 6 & MinGW on Windows 2000 (32-bit).
A simple 3-line program had the FPU control word set for 'Double precision' (0x027f) for VC++ and 'Extended precision' when compiled using MinGW (0x037f).
On the same machine, gcc/Linux-32 had the same extended precision (0x37f).
i.e. MinGW and gcc/Linux seems to be having the same FPU setting.