【问题标题】:How are denormalized floats handled in C#?在 C# 中如何处理非规范化的浮点数?
【发布时间】:2014-05-19 21:07:57
【问题描述】:

请阅读这篇fascinating article,了解您可以在具有非规范化浮点数(浮点数非常接近 0)的 Intel CPU 上获得 20x-200x 的减速。

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

C# 应用程序如何处理这个问题?是否有启用/禁用_MM_FLUSH_ZERO的选项?

【问题讨论】:

    标签: c# .net performance intel sse


    【解决方案1】:

    没有这样的选择。

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

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

    这确实给您带来了不让您的浮点计算像这样失控的负担。使用非正规计算几乎总是会产生无意义的结果,如果不是从极小的值,那么至少是从有效数字的快速丢失。将小于 2.2E-308 的值截断为 0 取决于您。是的,不是很实用。也许程序提供比正常慢一点的无意义结果是可以的:)

    【讨论】:

    • 虽然我完全接受您的回答,即无法完成,但我确实对这个问题的琐碎化持异议。但是在执行音频处理(例如数字滤波器、延迟线等)时,对 Singles 进行非规范化非常容易。鉴于 x86 架构上的性能损失是可怕的,请求抛出异常是非常好的。标量已经检查了操作。为什么不浮动呢?
    • Pinvoking _control87_2() 当代码被这样本地化时就不是问题了。使用 _DN_FLUSH,不要忘记将其设置回去。
    猜你喜欢
    • 2012-03-10
    • 2021-06-13
    • 2018-12-12
    • 2017-04-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多