C++/CLI y C#: Asombrosas diferencias en el optimizador de código (IV)

Por fin algo de coherencia en el tema. Vicente, en la segunda parte de esta serie, da en el clavo, pero el jitter sigue siendo bastante malo. ¿Por qué no hace el compilador de C# lo mismo que el de C++/CLI y deja más suelto el jitter. Sigo viéndolo un error bastante garrafal.

Vamos a ello.

Modifiquemos el programa y dejémoslo así:

using System; 
using System.Collections.Generic; 
using System.Text; 
 
namespace TestCS1 
{ 
    class Program 
    { 
        static void CallPrint() 
        { 
            //Console.WriteLine("CallPrint"); 
        } 
        static void DoWork() 
        { 
            for (int i = 0; i < 1000; i++) 
                CallPrint(); 
        } 
        static void Main(string[] args) 
        { 
            for(uint i=0;i<UInt32.MaxValue;i++) 
            //while(true) 
                DoWork(); 
            Console.WriteLine("Hello World"); 
        } 
    } 
} 

El cambio consiste en cambiar el bucle for dentro de main() por un bucle prácticamente infinito. Como nos comenta Vicente, si queremos ver al jitter en todo su esplendor, debemos o bien utilizar el depurador de línea de comando o bien anexar el Visual Studio a un proceso ya en ejecución (esto no lo sabía, yo pensaba que ejecutando bajo el depurador entraba todo en acción).

Compilamos el programa y lo lanzamos sin el depurador, es decir, pulsamos May-Alt-F5 o seleccionamos la opción correspondiente desde el menú Debug.

Una vez que hayamos lanzado el programa, nos vamos al menú Debug y seleccionamos «Attach to process», buscamos TestCS3 en la lista de procesos y una vez hecho eso, pausamos el programa anexado.

Después, vemos la ventana de «Disassembly» (quizás tengamos que ejecutar unos cuantos pasos o «Step out» para volver a main():

Vemos algo menos de código que en la versión sin jittear (permítaseme la expresión), pero seguimos teniendo la llamada a DoWork() que, aunque ya no llama al método vacío, sigue repitiendo un bucle bastante absurdo y sin sentido:

Supongo que el jitter habrá tenido tiempo de optimizar el código en las miles de pasadas que el programa haya podido realizar entre que lo lanzamos y lo anexamos al depurador (de hecho ya no vemos esas extrañas llamadas dentro del código).

Resumiendo: que sigue siendo mejor optimizar en la compilación (aunque evidentemente, también es bueno tener un jitter) que en tiempo de ejecución. De hecho, el código realizado en C++/CLI sigue siendo sensiblemente más rápido sin la pasada del jitter que el de C# con varias miles de vueltas…

Pero ahora surge otro problema muy serio: si el código en Release no es el mismo que cuando la máquina se ejecuta sola, seguro que habrá muchas diferencias entre el código que se ejcuta dentro del Visual Studio y el que lo hace fuera de él, es decir, no estamos completamente seguros de que nuestro código vaya a funcionar bien en otras máquinas (y es ahora cuando yo me explico los problemas que he tenido y sigo teniendo con el código en producción, que a veces no funciona como debiera…).

4 comentarios sobre “C++/CLI y C#: Asombrosas diferencias en el optimizador de código (IV)”

  1. Esto también tiene explicación: primero, hasta donde yo sé el código se jittea solo una vez, da lo mismo que se ejecute 2 veces o mil. Se jittea la primera vez que se ejecuta y así se queda para siempre.

    Respecto el porque no optimizar en compilación con C# se debe a que si optimizaras en compilación luego no podrías jittear. Para poder jittear necesitas que el código compilado no esté nada de nada optimizado (sería como pasar un compilador a la salida de otro compilador, seguro que no puede optimizar casi nada porque se encuentra las cosas de forma rara…).

    A los jitters hay que darles un poco más de tiempo aún, todavía están bastante verdes (y eso que el jitter de .NET no está nada mal ;)).

    Un saludo!

    Vicente

  2. Ok, entiendo eso. Pero entonces ¿Por qué el compilador de C++/CLI -recordemos que es también .NET- sí que optimiza? Personalmente prefiero un compilador-optimizador que un compilador-jitter.

  3. Realmlente en esa del compilador me pillas. La postura de MS creo que es que el que el compilador de C++/CLI optimice es un «artifact» de su herencia de C++ :p

    Un saludo!

    Vicente

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *