c – VS2015与VS2013的不同优化会导致浮点异常
在从VS2013过渡到VS2015期间,我遇到了一个小问题.在VS2015中进一步提到的代码示例导致浮点无效操作.
int main() { unsigned int enableBits = _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID; _clearfp(); _controlfp_s(0,~enableBits,enableBits); int count = 100; float array[100]; for (int i = 0; i < count; ++i) { array[i] = (float)pow((float)(count - 1 - i) / count,4); //this causes exception in VS2015 } return 0; } 这仅在发布模式下发生,因此可能由不同的优化引起.这段代码有什么问题,或者这是VS 2015中的错误? 很难在整个代码库中找到这样的问题所以我正在寻找一些系统的修复而不是一种解决方法(例如使用不同的变量代替i工作) 我还检查了生成的汇编代码,在VS2013中它似乎使用整个128位注册表在一个分区中执行4个浮点运算.在VS2015中,它似乎只执行2次浮点运算,其余的注册表为零(或一些垃圾)可能会引入此异常. 导致异常的指令在图中标出. VS2013 和VS2015 任何帮助将不胜感激. 解决方法
这看起来是使用浮点异常与您的交互,但也启用了一些浮点优化.
代码正在做的是它一次进行2次迭代(循环展开),但是使用divps,它同时进行4次除法(来自XMM寄存器中的4次浮点数). XMM寄存器中的上2个浮点数未使用,为零.由于不使用这些插槽中的值的除法,因此通常不重要.但是,当您设置自定义异常处理时,这会引发一个无效的op异常,即使它的生成值不会被使用,也会看到它. 正如我所看到的,您的选择是设置/ fp:strict,这将禁用优化,因此使其工作(但显然会使代码变慢)或删除controlfp调用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |