Límites de matriz verifica la eliminación en el CLR?
-
25-10-2019 - |
Pregunta
Recientemente estaba leyendo Este artículo por Dave Detlefs en los que presenta algunos casos en los que el CLR realiza la eliminación de verificación de límites de matriz. Decidí probar esto yo mismo, así que hice lo siguiente:
- Abierto Visual Studio 2010 Ultimate SP1
- Creó un nuevo proyecto C# de la aplicación de consola de tipo (apuntar al perfil del cliente .NET 4 de forma predeterminada)
Se agregó el siguiente código (todos los sub-métodos se toman directamente del artículo):
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]; } }
Cambiado al modo de liberación; Verificado que el "código de optimización" se verifica en las opciones de compilación
- Se agregó un punto de interrupción a cada acceso a la matriz, comenzó a depurar (F5) y abrió la ventana de desasmblado
Así que aquí está el desasmblado para un [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
El CMP/JB/Call es verificación de límites, en realidad forzando la llamada a ejecutarse, lanza una indexOutoFrangeException.
Lo mismo para todos los accesos de matriz, incluido el acceso redundante en test_simpledundant. Entonces, ¿hay algo mal con mi metodología de prueba, o el CLR en realidad no elimina la verificación de límites? Espero estar equivocado y, de ser así, me gustaría saber cómo realmente puedo obtener la eliminación de los límites de matriz.
Solución
Gracias a un comentario de Cody Gray, he logrado responder a mi propia pregunta:
Por defecto, las optimizaciones JIT se deshabilitan al depurar. Para solucionar esto, uno puede ir a depurar -> opciones y configuraciones -> depuración -> general y desmarque "habilite solo mi código" y "suprima la optimización JIT en la carga del módulo".
Ver también http://msdn.microsoft.com/en-us/library/ms241594.aspx
Con la optimización habilitada, la verificación de límites se elimina como se anuncia.
Dejaré esto aquí para fines de documentación.