什么可以改变我背后的浮点控制字?

时间:2011-10-07 13:05:03

标签: python c windows delphi floating-point

我有一个32位Windows应用程序,主要用Delphi编写,它使用8087 FPU执行浮点数值模拟。我最近添加了通过python2x.dll使用Python API链接外部Python代码的功能。最近的这一变化导致了一些非常奇怪的行为。

应用程序具有批处理操作模式,可以并行执行多个模拟,以利用多核架构。一旦在此过程中执行了Python代码,我就开始在不同的线程上看到对8087控制字的更改。我已经仔细检查了这一点,并且我已经观察到控制字已经改变,即使在一个从未调用过Python DLL的线程中也是如此。

我知道这听起来很奇妙,但是,正如我所发现的那样,有一些机制可以表明这种行为。我已经了解了信号。我首先假设Python DLL正在设置进程范围的信号处理程序(通过调用signal()),这些信号处理程序负责更改控制字。例如,与Python代码无关的线程可能会导致SIGFPE,而这反过来可能会修改控制字。

我宁愿得出signal()不是机制的结论。我安排在启动时执行Python代码。然后我将信号处理程序设置回SIG_DFL。然后我开始模拟。但仍然发生了控制字的变化。

我的问题(最后)是否有人知道可以通过这种方式改变控制字的另一种机制。我想我正在寻找中断,APC等等!

更新

控制字将更改为0x037F,即英特尔默认值。这与MSVC / Windows默认值0x027F不同。我假设某事正在调用FPINIT

我还发现Py_InitializeEx允许调用者停止Python设置信号处理程序。即使我使用这种方法进行初始化,控制字也会发生变化,所以我更加确信这不是机制。

3 个答案:

答案 0 :(得分:5)

例如,使用DllMain标记的DLL_THREAD_ATTACH来电,请参阅msdn

<强>更新

我找到了类似问题的链接 - DLL Load "Poisons" FPU Control Word for New Threads。但是,是的,它是关于在 Dll加载后创建的线程。

答案 1 :(得分:1)

如果我没记错的话,这就是德尔福的问题。有关此问题herehere的一些讨论。我记得在尝试在Delphi中编写一些VST插件时碰到它。

答案 2 :(得分:0)

我见过这样的情况,默认打印机的打印机驱动程序改变了我背后的控制字。当我更改默认打印机时,问题就消失了。 为了避免这个问题,我将控制字设置为适当位置的默认值:

_control87(_CW_DEFAULT, _CW_DEFAULT);

我在安装了Norton Security 2011的客户的所有机器上也看到了同样的问题,但是问题因打印机驱动程序的修复而消失,所以我不确定诺顿是否真的是原因。