简体   繁体   English

JIT .Net编译器错误?

[英]JIT .Net compiler bug?

The result of the following Code differs If it is started with the debugger in the background or without. 以下代码的结果不同如果它在后台启动调试器或没有调试器。 The difference is only there, if optimization is switched on. 如果开启优化,那么差异就在那里。

This is the result: 这是结果:

-> with optimazation: 1000 2008 3016 1001 2009 3007 ... - >与优化:1000 2008 3016 1001 2009 3007 ...

-> without optimization ( as expected ) 1000 1008 1016 1001 1009 1017 ... - >无优化(如预期)1000 1008 1016 1001 1009 1017 ...

Code: 码:

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace OptimizerTest
{   
    public class Test
    {
        int dummy;

        public void TestFunction(int stepWidth)
        // stepWidth must be a parameter
        {
            for (int step = 0; step < stepWidth; step++)
            {
                dummy = step + 1000;
                // addition with constant ( same value as later !)
                for (int x = 0; x < 20; x += stepWidth)
                {
                    int index = x + 1000 + step;
                    // constant must be same as above and ?!?! 
                    // int index = x + step + 1000; works !!!!!
                    Console.Write("\n\r" + index);
                }
            }
        }

        [MethodImpl(MethodImplOptions.NoOptimization)]
        public void TestFunctionNoOptimization(int stepWidth)
        {
            for (int step = 0; step < stepWidth; step++)
            {
                dummy = step + 1000;
                for (int x = 0; x < 20; x += stepWidth)
                {
                    int index = x + 1000 + step;                        
                    Console.Write("\n\r" + index);
                }
            }
        }
    }

    class Program
    {
        /// <summary>
        /// Result differs from Start with F5 to Ctrl-F5
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Test test = new Test();
            Console.Write("\n\r---------\n\roptimized result\n\r-------------" );
            test.TestFunction(8);
            Console.Write("\n\r---------\n\rnot optimized result\n\r-------------");
            test.TestFunctionNoOptimization(8);
            Console.Write("\n\r---------\n\rpress any key");
            Console.ReadKey();
        }
    }
}

The behavior of the error depends on the number of iterations of the inner loop (x<5 everything works fine). 错误的行为取决于内循环的迭代次数(x <5一切正常)。 Very interesting is that the does not occure when I use 非常有趣的是,当我使用时不会发生

   int index = x + step + 1000; 

instead of 代替

   int index = x + 1000 + step; 

I am working with Visual Studio 2010 SP1 and tried it with .NET Framework from 2.0 to 4.0.3. 我正在使用Visual Studio 2010 SP1并尝试使用.NET Framework从2.0到4.0.3。 I've always seen the same result. 我总是看到同样的结果。

Does anybody know about this bug or can reproduce? 有人知道这个bug还是可以重现?

Yes, this is definitely a jitter optimizer bug. 是的,这绝对是一个抖动优化器错误。 The reason other SO users have trouble reproducing it is because only the x64 jitter appears to have this bug. 其他SO用户重现它的原因是因为只有x64抖动似乎有这个bug。 You must set the project's Platform target to AnyCPU, untick the "Prefer 32-bit" option on VS2012 and up. 您必须将项目的平台目标设置为AnyCPU,在VS2012及更高版本上取消选中“首选32位”选项。

I haven't looked at the underlying reason closely enough but it appears to fumble at trying to eliminate the common step + 1000 sub-expression. 我没有仔细研究潜在的原因,但似乎在尝试消除共同的step + 1000子表达时摸索。 Sub-expression elimination is one of the standard jitter optimizations. 子表达式消除是标准抖动优化之一。 But it incorrectly incorporates the expression code inside the loop instead of keeping it out of the loop as written. 但是它错误地将表达式代码合并到循环中,而不是像写入的那样将它保持在循环之外。 You'll for example see the bug disappear when you write: 例如,当您写下时,您会看到错误消失:

  dummy = step + 999;

This bug is still present in the latest .NET 4.5.1 version (clrjit.dll, v4.0.30319.34003 on my machine), also present in the v2 jitter (mscorjit.dll, v2.0.50727.7905 on my machine). 最新的.NET 4.5.1版本(我的机器上的clrjit.dll,v4.0.30319.34003)中仍然存在此错误,也存在于v2抖动(我机器上的mscorjit.dll,v2.0.50727.7905)中。

The code is a bit too synthetic to recommend a solid workaround, you already found one anyway so you can keep motoring on your project. 代码有点太合成了,无法推荐一个可靠的解决方法,你已经找到了一个,所以你可以继续驾驶你的项目。 In general, I'd recommend you eliminate the sub-expression yourself with: 一般来说,我建议您自己删除子表达式:

  int index = x + dummy;  

It should be reported to Microsoft, you can so so by posting a bug report at connect.microsoft.com. 应该向Microsoft报告,您可以通过在connect.microsoft.com上发布错误报告来实现。 If you don't want to take the time then let me know and I'll take care of it. 如果你不想花时间让我知道,我会照顾它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM