Frage

Ich habe vor kurzem gelesen Dieser Artikel von Dave detlefs, in dem er einige Fälle vorstellt, in denen die CLR Array -Grenzen überprüft, überprüft die Eliminierung. Ich beschloss, dies selbst zu testen, also habe ich Folgendes gemacht:

  • Eröffnet Visual Studio 2010 Ultimate SP1
  • Erstellt ein neues C# -Projekt der Typ -Konsolenanwendung (Targeting .net 4 Client -Profil standardmäßig)
  • Der folgende Code fügte hinzu (alle Untermethoden werden direkt aus dem Artikel genommen):

    class Program {
        static void Main(string[] args) {
            int[] array = new int[30];
            Test_SimpleAscend(array);
            Test_SimpleRedundant(array, 3);
    
            foreach (int i in array) {
                Console.WriteLine(i);
            }
        }
    
        static void Test_SimpleAscend(int[] a) {
            for (int i = 0; i < a.Length; i++)
                a[i] = i;
        }
    
        static void Test_SimpleRedundant(int[] a, int i) {
            int k = a[i];
            k = k + a[i];
        }
    }
    
  • Zum Release -Modus umgestellt; Überprüft, ob der "Code optimieren" in den Build -Optionen überprüft wird

  • Zu jedem Array -Zugriff einen Haltepunkt hinzugefügt, begann Debugging (F5) und öffnete das Dissembly -Fenster

Also hier ist die Unterscheidung für ein [i] = i; In test_simpleascend:

                a[i] = i;
00000024  mov         eax,dword ptr [ebp-4] 
00000027  mov         edx,dword ptr [ebp-8] 
0000002a  cmp         eax,dword ptr [edx+4] 
0000002d  jb          00000034 
0000002f  call        64FD6E08 
00000034  mov         ecx,dword ptr [ebp-4] 
00000037  mov         dword ptr [edx+eax*4+8],ecx 

Der CMP/JB/CALL ist eine Grenzenprüfung, wodurch der Aufruf zur Ausführung eine IndexoutofRangeException ausgelöst wird.

Gleiches gilt für alle Array -Zugriffe, einschließlich des redundanten Zugriffs in Test_Simpledundundant. Stimmt also etwas mit meiner Testmethodik nicht, oder der CLR beseitigt keine Grenzenprüfung? Ich hoffe, ich liege falsch und wenn ja, würde ich gerne wissen, wie ich wirklich Array -Grenzen bekommen kann, um die Eliminierung zu überprüfen.

War es hilfreich?

Lösung

Dank eines Kommentars von Cody Gray habe ich meine eigene Frage beantwortet:

Standardmäßig sind JIT -Optimierungen beim Debuggen deaktiviert. Um dies zu beheben, kann man zu Debug -> Optionen und Einstellungen -> Debugging -> Allgemein gehen und sowohl "nur meinen Code aktivieren" und "JIT -Optimierung bei Modullast unterdrücken".

Siehe auch http://msdn.microsoft.com/en-us/library/ms241594.aspx

Bei aktivierter Optimierung werden die Grenzenprüfung wie angekündigt entfernt.

Ich werde das hier für Dokumentationszwecke lassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top