incomum de desempenho de loop for no .NET x64: afinidade de número-iteração par?

Executando um loop vazio com um grande número de iterações, estou obtendo números muito diferentes em quanto tempo leva para executar:

public static class Program
{
    static void Main()
    {
        var sw = new Stopwatch();
        sw.Start();
        for (var i = 0; i < 1000000000; ++i)
        {
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);
    }
}

O acima será executado em cerca de 200ms na minha máquina, mas se eu aumentá-lo para 1000000001, então é preciso4x contanto! Então, se eu fizer isso 1000000002, então é para baixo de 200ms novamente!

esteparece acontecer para um número par de iterações. Se eu forfor (var i = 1; i < 1000000001, (nota começando em 1 em vez de 0), então são 200ms. Ou se eu fizeri <= 1000000001 (note menos queou igualentão são 200ms. Ou(var i = 0; i < 2000000000; i += 2) também.

Isso parece ser apenas em x64, mas em todas as versões do .NET até (pelo menos) 4.0. Também aparece apenas quando no modo de liberação com o depurador desconectado.

ATUALIZAR Eu estava pensando que isso era provavelmente devido a um pouco de mudança inteligente no jit, mas o seguinte parece refutar isso: se você fizer algo como criar um objeto dentro desse loop, entãonaquela leva cerca de 4x também:

public static class Program
{
    static void Main()
    {
        var sw = new Stopwatch();
        sw.Start();
        object o = null;
        for (var i = 0; i < 1000000000; i++)
        {
            o = new object();
        }
        sw.Stop();
        Console.WriteLine(o); // use o so the compiler won't optimize it out
        Console.WriteLine(sw.ElapsedMilliseconds);
    }
}

Isso leva cerca de 1 segundo na minha máquina, mas depois aumenta em 1 a 10000000014 segundos. Isso é um extra de 3000ms, por isso não poderia ser devido a mudança de bits, como isso teria aparecido como uma diferença de 3000ms no problema original também.

questionAnswers(1)

yourAnswerToTheQuestion