Следующий код дает различный вывод при запуске выпуска внутри Visual Studio и при запуске выпуска вне Visual Studio. Я использую Visual Studio 2008 и ориентируюсь на .NET 3.5. Я также пробовал .NET 3.5 SP1.
При работе вне Visual Studio должен включиться JIT. Либо (а) что-то неуловимое происходит с C #, которого мне не хватает, либо (б) JIT на самом деле ошибается. Я сомневаюсь, что JIT может пойти не так, но у меня заканчиваются другие возможности ...
Вывод при запуске внутри Visual Studio:
0 0,
0 1,
1 0,
1 1,
Вывод при запуске релиза вне Visual Studio:
0 2,
0 2,
1 2,
1 2,
Какова причина?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
struct IntVec
{
public int x;
public int y;
}
interface IDoSomething
{
void Do(IntVec o);
}
class DoSomething : IDoSomething
{
public void Do(IntVec o)
{
Console.WriteLine(o.x.ToString() + " " + o.y.ToString()+",");
}
}
class Program
{
static void Test(IDoSomething oDoesSomething)
{
IntVec oVec = new IntVec();
for (oVec.x = 0; oVec.x < 2; oVec.x++)
{
for (oVec.y = 0; oVec.y < 2; oVec.y++)
{
oDoesSomething.Do(oVec);
}
}
}
static void Main(string[] args)
{
Test(new DoSomething());
Console.ReadLine();
}
}
}
Ответы:
Это ошибка оптимизатора JIT. Он развертывает внутренний цикл, но не обновляет значение oVec.y должным образом:
Ошибка исчезает, когда вы увеличиваете oVec.y до 4, это слишком много вызовов, чтобы развернуть.
Один из способов это:
ОБНОВЛЕНИЕ: перепроверено в августе 2012 года, эта ошибка была исправлена в версии 4.0.30319 джиттер. Но все еще присутствует в джиттер v2.0.50727. Кажется маловероятным, что они исправят это в старой версии после этого долгого времени.
источник
Я полагаю, что это в подлинной ошибке компиляции JIT. Я хотел бы сообщить об этом в Microsoft и посмотреть, что они говорят. Интересно, что я обнаружил, что у x64 JIT нет той же проблемы.
Вот мое чтение x86 JIT.
Это похоже на оптимизацию, которая мне не понравилась ...
источник
Я скопировал ваш код в новое консольное приложение.
Так что это x86 JIT неправильно генерирует код. Удалили мой оригинальный текст о переупорядочении циклов и т. Д. Несколько других ответов подтвердили, что JIT неправильно разматывает цикл в x86.
Чтобы решить эту проблему, вы можете изменить объявление IntVec на класс, и он работает во всех вариантах.
Думаю, для этого нужно перейти на MS Connect ....
-1 в Microsoft!
источник