CLR JIT优化违反了因果关系? [英] CLR JIT optimizations violates causality?

查看:249
本文介绍了CLR JIT优化违反了因果关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个启发性的例子的一个同事告诉他为什么测试浮相等往往是一个坏主意。我去的例子是添加.1十次,比对1.0(一个我一直在我的入门级数字显示)。我很惊讶地发现,这两个结果的都是平等的的( code +输出

I was writing an instructive example for a colleague to show him why testing floats for equality is often a bad idea. The example I went with was adding .1 ten times, and comparing against 1.0 (the one I was shown in my introductory numerical class). I was surprised to find that the two results were equal (code + output).

float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
    @float += 0.1f;
}
Console.WriteLine(@float == 1.0f);

一些调查显示,这个结果不能在(很像浮动平等)依赖。一个我发现最令人惊讶的是,增加code 其他code可以改变计算的结果(的 code +输出)。注意,这个例子具有完全相同的code和白细胞介素,多一个线C#附加的。

Some investigation showed that this result could not be relied upon (much like float equality). The one I found most surprising was that adding code after the other code could change the result of the calculation (code + output). Note that this example has exactly the same code and IL, with one more line of C# appended.

float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
    @float += 0.1f;
}
Console.WriteLine(@float == 1.0f);
Console.WriteLine(@float.ToString("G9"));

我知道我不应该使用的彩车平等,因此不应该太在意这一点,但我发现它是相当令人惊讶的,因为有每个人我已经展示了这。做的东西的的您进行了计算改变了preceding计算的价值?我不认为这是计算人的模型通常有他们的想法。

I know I'm not supposed to use equality on floats and thus shouldn't care too much about this, but I found it to be quite surprising, as have about everyone I've shown this to. Doing stuff after you've performed a calculation changes the value of the preceding calculation? I don't think that's the model of computation people usually have in their minds.

我不完全难倒,似乎是安全的假设,有一些类型的优化中,改变了计算结果的平等的情况下发生的(楼在调试模式prevents平等的情况下) 。显然,优化抛弃时,CLR发现它以后将需要框浮动。

I'm not totally stumped, it seems safe to assume that there's some kind of optimization occurring in the "equal" case that changes the result of the calculation (building in debug mode prevents the "equal" case). Apparently, the optimization is abandoned when the CLR finds that it will later need to box the float.

我搜索了一下,但苦于找不到原因的行为。任何人都可以给我介绍?

I've searched a bit but couldn't find a reason for this behavior. Can anyone clue me in?

推荐答案

这是的方式的副作用的JIT优化工程。它做更多的工作,如果有小于code生成。在原始片段中循环被编译到这一点:

This is a side effect of the way the JIT optimizer works. It does more work if there is less code to generate. The loop in your original snippet gets compiled to this:

                @float += 0.1f;
0000000f  fld         dword ptr ds:[0025156Ch]          ; push(intermediate), st0 = 0.1
00000015  faddp       st(1),st                          ; st0 = st0 + st1
            for (int @int = 0; @int < 10; @int += 1) {
00000017  inc         eax  
00000018  cmp         eax,0Ah 
0000001b  jl          0000000F 

当你添加额外的Console.WriteLine()语句,它编译到这一点:

When you add the extra Console.WriteLine() statement, it compiles it to this:

                @float += 0.1f;
00000011  fld         dword ptr ds:[00961594h]          ; st0 = 0.1
00000017  fadd        dword ptr [ebp-8]                 ; st0 = st0 + @float
0000001a  fstp        dword ptr [ebp-8]                 ; @float = st0
            for (int @int = 0; @int < 10; @int += 1) {
0000001d  inc         eax  
0000001e  cmp         eax,0Ah 
00000021  jl          00000011 

请注意,在地址15差值Vs地址17 + 1A,第一循环保持中间结果的FPU。第二环路将其存储回@float局部变量。而它停留FPU的内部,其结果是计算出的全precision。然而,存储回截断中间结果返回给一个浮动,失去了大量的precision位的过程。

Note the difference at address 15 vs address 17+1a, the first loop keeps the intermediate result in the FPU. The second loop stores it back to the @float local variable. While it stays inside the FPU, the result is calculated with full precision. Storing it back however truncates the intermediate result back to a float, losing lots of bits of precision in the process.

虽然不快,我不认为这是一个错误。在64位JIT编译器的行为不同呢。您可以在connect.microsoft.com

While unpleasant, I don't believe this is a bug. The x64 JIT compiler behaves differently yet. You can make your case at connect.microsoft.com

这篇关于CLR JIT优化违反了因果关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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