Jan*_*Jan 22 .net c# jit visual-studio-2010
以下代码的结果不同如果它在后台启动调试器或没有调试器.如果开启优化,那么差异就在那里.
这是结果:
- >与优化:1000 2008 3016 1001 2009 3007 ...
- >无优化(如预期)1000 1008 1016 1001 1009 1017 ...
码:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误的行为取决于内循环的迭代次数(x <5一切正常).非常有趣的是,当我使用时不会发生
int index = x + step + 1000;
Run Code Online (Sandbox Code Playgroud)
代替
int index = x + 1000 + step;
Run Code Online (Sandbox Code Playgroud)
我正在使用Visual Studio 2010 SP1并尝试使用.NET Framework从2.0到4.0.3.我总是看到同样的结果.
有人知道这个bug还是可以重现?
Han*_*ant 20
是的,这绝对是一个抖动优化器错误.其他SO用户重现它的原因是因为只有x64抖动似乎有这个bug.您必须将项目的平台目标设置为AnyCPU,在VS2012及更高版本上取消选中"首选32位"选项.
我没有仔细研究潜在的原因,但似乎在试图消除共同的step + 1000子表达时摸索.子表达式消除是标准抖动优化之一.但是它错误地将表达式代码合并到循环中,而不是像写入的那样将它保持在循环之外.例如,当您写下时,您会看到错误消失:
dummy = step + 999;
Run Code Online (Sandbox Code Playgroud)
最新的.NET 4.5.1版本(我的机器上的clrjit.dll,v4.0.30319.34003)中仍然存在此错误,也存在于v2抖动(我机器上的mscorjit.dll,v2.0.50727.7905)中.
代码有点过于合成,无法推荐一个可靠的解决方法,你已经找到了一个,所以你可以继续驾驶你的项目.一般来说,我建议您自己删除子表达式:
int index = x + dummy;
Run Code Online (Sandbox Code Playgroud)
应该向Microsoft报告,您可以通过在connect.microsoft.com上发布错误报告来实现.如果你不想花时间让我知道,我会照顾它.
| 归档时间: |
|
| 查看次数: |
1075 次 |
| 最近记录: |