为什么不MSVS优化掉+ 0?相反,它把它变成一个非规格化浮动? [英] Why does MSVS not optimize away +0? Instead, it turns it into a denormalized float?

查看:136
本文介绍了为什么不MSVS优化掉+ 0?相反,它把它变成一个非规格化浮动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这<一个href=\"http://stackoverflow.com/questions/9314534/why-does-changing-0-1f-to-0-slow-down-performance-by-10x\">question说明了一个非常有趣的现象:非规范化慢漂下来code级以上的订单

该行为是在接受的答案很好的解释。然而,有一个评论,以目前48 upvotes,我无法找到满意的答案:


  

为什么没有编译器只是删除在这种情况下+/- 0?!? -
  迈克尔·多根


<子>附注:我有IM pression即0F是/必须精确重新presentable(而且 - 这是二重presentation必须全部是零),但无法找到这种说法在C11标准。引述证明这一点,或论点驳斥这种说法,将是最欢迎的。无论如何,迈克尔的的问题是最主要的问题在这里。


§5.2.4.2.2


  

这是实现可能给予零和值没有浮点
  号码(如无穷大和NaN)的标志,也可以让他们
  无符号的。



解决方案

编译器不能消除又多了一个浮点正零的,因为它不是一个身份操作。通过IEEE 754规则,添加+ 0的结果。为-0。是不是-0;这是+ 0。

编译器可以消除+0减法。或添加的-0。因为那些是身份的操作。

例如,当我编译如下:

 双富(双X){返回X + 0; }

与苹果GNU C 4.2.1使用 -O3 在Intel Mac上,生成的程序集code包含 addsd LC0(RIP% ),%XMM0 。当我编译如下:

 双富(双X){返回X  -  0; }

不存在添加指令;大会仅返回其输入。

所以,它很可能在原来的问题code包含此声明的附加指令:

  Y [i] = Y [I] + 0;

但包含了一个该声明没有说明:

  Y [i] = Y [I]  -  0;

不过,第一条语句涉及算术与低于正常值 Y [I] ,所以这是足以程序慢下来。

This question demonstrates a very interesting phenomenon: denormalized floats slow down the code more than an order of magnitude.

The behavior is well explained in the accepted answer. However, there is one comment, with currently 48 upvotes, that I cannot find satisfactory answer to:

Why isn't the compiler just dropping the +/- 0 in this case?!? – Michael Dorgan

Side note: I have the impression that 0f is/must be exactly representable (furthermore - it's binary representation must be all zeroes), but can't find such a claim in the c11 standard. A quote proving this, or argument disproving this claim, would be most welcome. Regardless, Michael's question is the main question here.


§5.2.4.2.2

An implementation may give zero and values that are not floating-point numbers (such as infinities and NaNs) a sign or may leave them unsigned.

解决方案

The compiler cannot eliminate the addition of a floating-point positive zero because it is not an identity operation. By IEEE 754 rules, the result of adding +0. to -0. is not -0.; it is +0.

The compiler may eliminate the subtraction of +0. or the addition of -0. because those are identity operations.

For example, when I compile this:

double foo(double x) { return x + 0.; }

with Apple GNU C 4.2.1 using -O3 on an Intel Mac, the resulting assembly code contains addsd LC0(%rip), %xmm0. When I compile this:

double foo(double x) { return x - 0.; }

there is no add instruction; the assembly merely returns its input.

So, it is likely the code in the original question contained an add instruction for this statement:

y[i] = y[i] + 0;

but contained no instruction for this statement:

y[i] = y[i] - 0;

However, the first statement involved arithmetic with subnormal values in y[i], so it was sufficient to slow down the program.

这篇关于为什么不MSVS优化掉+ 0?相反,它把它变成一个非规格化浮动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆