Tableau Bounds Check élimination dans le CLR?
-
25-10-2019 - |
Question
Je lisais récemment cet article par Dave Detlefs dans lequel il présente quelques cas où les limites du tableau PerForm CLR vérifient l'élimination. J'ai décidé de tester moi-même, donc je l'ai fait ce qui suit:
- Ouvert Visual Studio 2010 Ultimate SP1
- A créé un nouveau C # projet de type Application console (ciblage .NET 4 Client Profile par défaut)
-
Ajout le code suivant (tous les sous-méthodes sont prises directement à partir de l'article):
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]; } }
-
Switched en mode de sortie; vérifié que "Optimize Code" est cochée dans les options de construction
- Ajout d'un point d'arrêt à chaque accès au tableau, a commencé le débogage (F5) et a ouvert la fenêtre Démontage
Alors, voici le désassemblage pour [i] = i; en 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
Le cmp / jb / appel vérification des limites, ce qui oblige effectivement l'appel à exécuter le renvoi d'une IndexOutOfRangeException.
Même chose pour tous les accès de réseau, y compris l'accès redondant à Test_SimpleRedundant. Donc, il y a quelque chose de mal avec ma méthode d'essai, ou le CLR n'élimine pas réellement vérification des limites? J'espère que je me trompe et si oui je voudrais savoir comment je peux vraiment obtenir des limites du tableau de vérifier l'élimination.
La solution
Merci à un commentaire par Cody Gray, j'ai réussi à répondre à ma propre question:
Par défaut, JIT Optimisations sont désactivées lors du débogage. Pour résoudre ce problème, on peut aller à Debug -> Options et Paramètres -> Debugging -> Général et décochez les deux « Activer juste mon code » et « Optimisation sur JIT Suppress charge du module ».
Voir aussi http://msdn.microsoft.com/en-us/ bibliothèque / ms241594.aspx
Avec l'optimisation activée, les limites retour sont retirés comme prévu.
Je vais laisser ce ici à des fins de documentation.