.net-如何在C#中处理非规范化的浮点数?

只需阅读这篇引人入胜的文章,了解具有非标准浮点数(浮点数非常接近0)的Intel CPU可能出现的20x-200x减速。

SSE有一个选项可以将这些值四舍五入为0,遇到这种浮点值时可以恢复性能。

C#应用程序如何处理此问题? 有启用/禁用_MM_FLUSH_ZERO的选项吗?

Robinicks asked 2020-01-13T08:32:39Z
1个解决方案
47 votes

没有这样的选择。

C#应用程序中的FPU控制字在启动时由CLR初始化。 更改它不是框架提供的选项。 即使您尝试通过_control87_2()更改它,它也不会持续很长时间。 任何异常都会导致CLR内部的异常处理实现再次重置控制字。 它是为处理FPU控制字的另一个方面而编写的,它允许取消掩盖浮点异常。 这也将不利于任何其他期望全局状态不会像这样改变的托管代码。

在虚拟机中运行代码时,隐含的限制是无法直接控制硬件。 这也不是在本机代码中也很容易做到,当库过于期望FPU具有默认初始化时,它们往往会表现出错误的行为。 特别是与异常屏蔽标志有关的问题,使用Borland工具创建的DLL具有打开异常的诀窍,这使得其他代码无法处理此类异常而失败。 FPU控制字是您要想像的最糟糕的全局变量,因此要解决的问题非常棘手。

这确实给您带来负担,不要让您的浮点计算陷入困境。 用非正规数进行计算几乎总是会产生无意义的结果,如果不是从根本上较小的值出发,至少是从有效数字的快速损失中得出。 截断值小于2.2E-308到0由您决定。 是的,不是很实用。 程序传递废话结果也许比正常情况还慢:)

Hans Passant answered 2020-01-13T08:33:13Z
translate from https://stackoverflow.com:/questions/22915543/how-are-denormalized-floats-handled-in-c