【发布时间】:2014-05-19 21:07:57
【问题描述】:
请阅读这篇fascinating article,了解您可以在具有非规范化浮点数(浮点数非常接近 0)的 Intel CPU 上获得 20x-200x 的减速。
SSE 有一个选项可以将这些值四舍五入为 0,从而在遇到此类浮点值时恢复性能。
C# 应用程序如何处理这个问题?是否有启用/禁用_MM_FLUSH_ZERO的选项?
【问题讨论】:
标签: c# .net performance intel sse
请阅读这篇fascinating article,了解您可以在具有非规范化浮点数(浮点数非常接近 0)的 Intel CPU 上获得 20x-200x 的减速。
SSE 有一个选项可以将这些值四舍五入为 0,从而在遇到此类浮点值时恢复性能。
C# 应用程序如何处理这个问题?是否有启用/禁用_MM_FLUSH_ZERO的选项?
【问题讨论】:
标签: c# .net performance intel sse
没有这样的选择。
C# 应用程序中的 FPU 控制字在启动时由 CLR 初始化。更改它不是框架提供的选项。即使您尝试通过调用_control87_2() 来更改它,它也不会持续很长时间;任何异常都会导致控制字被 CLR 中的异常处理实现再次重置。这是为了处理 FPU 控制字的另一个方面而编写的,它允许取消屏蔽浮点异常。这也将不利于任何其他不期望全局状态像那样更改的托管代码。
当您在虚拟机中运行代码时,无法直接控制硬件是一个隐含的限制。并不是说这在本机代码中也很容易做到,当库也期望 FPU 具有默认初始化时,它们往往会出现行为不端。特别是异常屏蔽标志的问题,使用 Borland 工具创建的 DLL 具有打开异常的诀窍,使其他不是为处理此类异常而编写的代码失败。一个非常难解决的问题,FPU 控制字是你能想象到的最糟糕的全局变量。
这确实给您带来了不让您的浮点计算像这样失控的负担。使用非正规计算几乎总是会产生无意义的结果,如果不是从极小的值,那么至少是从有效数字的快速丢失。将小于 2.2E-308 的值截断为 0 取决于您。是的,不是很实用。也许程序提供比正常慢一点的无意义结果是可以的:)
【讨论】: