Eigenartigkeit der For-Loop-Leistung in .NET x64: Affinität für geradzahlige Iteration?

Wenn ich eine leere for-Schleife mit einer großen Anzahl von Iterationen durchführe, erhalte ich in Bezug auf die Ausführungsdauer ganz andere Zahlen:

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);
    }
}

Das obige wird in ungefähr 200 ms auf meinem Computer ausgeführt, aber wenn ich es auf 1000000001 erhöhe, dauert es4x so lange! Wenn ich dann 1000000002 mache, dann sind es wieder 200ms!

Diesescheint für eine gerade Anzahl von Iterationen passieren. Wenn ich gehefor (var i = 1; i < 1000000001, (notiere beginnend bei 1 statt 0), dann sind es 200ms. Oder wenn dochi <= 1000000001 (notiere weniger alsoder gleich) dann sind es 200ms. Oder(var i = 0; i < 2000000000; i += 2) auch.

Dies scheint nur auf x64 zu sein, aber auf allen .NET-Versionen bis (mindestens) 4.0. Außerdem wird es nur im Release-Modus mit getrenntem Debugger angezeigt.

AKTUALISIEREN Ich dachte, dass dies wahrscheinlich auf eine clevere Bitverschiebung im JIT zurückzuführen ist, aber das Folgende scheint dies zu widerlegen: Wenn Sie so etwas wie ein Objekt in dieser Schleife erstellen, dannDas dauert auch ca. 4x so lange:

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);
    }
}

Dies dauert auf meinem Computer ungefähr 1 Sekunde, wird dann aber um 1 auf 1000000001 erhöht4 Sekunden. Das sind zusätzliche 3000 ms, also kann es nicht wirklich an Bitverschiebungen liegen, da sich dies auch als 3000 ms Unterschied im ursprünglichen Problem herausgestellt hätte.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage