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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top