Tarea 2 - 1 Explicar el modelo de compilación de programas .NET
Bueno, en realidad este tema ya se trató en un blog anterior, pero aquí se va a ampliar un poco, ya que es interesante.
Se acuerdan del CLR??? como les comentaba, es el que se encarga de compilar el IL a lenguaje nativo... pero bueno, vamos por partes.
Cada vez que se usa un lenguaje de programación para crear una aplicación (puede ser cualquier lenguaje, pero en este caso vamos a hablar de Microsoft, así que digamos que uso C#) el compilador de C# genera un código intermedio, llamado MSIL. Este código en realidad no me sirve de nada, ya que no puede correr en ninguna plataforma.
Bueno, ahora que tengo ese MSIL, entra en juego el CLR, el cual utilizando un compilador llamado JIT, generará el código nátivo para una plataforma en específico. El siguiente diagrama lo explica mejor:
Se acuerdan del CLR??? como les comentaba, es el que se encarga de compilar el IL a lenguaje nativo... pero bueno, vamos por partes.
Cada vez que se usa un lenguaje de programación para crear una aplicación (puede ser cualquier lenguaje, pero en este caso vamos a hablar de Microsoft, así que digamos que uso C#) el compilador de C# genera un código intermedio, llamado MSIL. Este código en realidad no me sirve de nada, ya que no puede correr en ninguna plataforma.
Bueno, ahora que tengo ese MSIL, entra en juego el CLR, el cual utilizando un compilador llamado JIT, generará el código nátivo para una plataforma en específico. El siguiente diagrama lo explica mejor:
Ok, esto ya se habia explicado anteriormente, y es bastante sencillo de comprender... sin embargo, en esta ocasión vamos a explicar un poco mas a fondo este proceso.
La primera aclaración importante, es que esta compilación es hecha a medida que se vaya necesitando. Esto significa que cuando un objeto es referenciado por primera vez, se compila y se manda a caché, y cada vez que se utilice otra vez, se va a tomar desde ahí. Por supuesto, esto también significa que el código compilado nativo, al estar en cache, va a tener que ser creado cada vez que se ejecute la aplicación. Esta aclaración es importante, porque algunas personas tienen la idea de que el código nativo resultante se guarda en disco (lo cual seria posible, pero no es el default).
Se podría pensar que este arreglo podria ser inclusive mas costoso que el "estilo" anterior (donde todo el código se compilaba al cargar la aplicación). Sin embargo, este costo extra no es tan grande. Y en el dado caso de que el performance sea un factor altamente determinante, existe una solución.
Existen en realidad dos "sabores" o versiones del JIT. El primero, que es el que se usa por default, no solamente realiza la compilación, sino que ademas lleva a cabo algunas optimizaciones "al vuelo", con las siguientes ventajas:
La primera aclaración importante, es que esta compilación es hecha a medida que se vaya necesitando. Esto significa que cuando un objeto es referenciado por primera vez, se compila y se manda a caché, y cada vez que se utilice otra vez, se va a tomar desde ahí. Por supuesto, esto también significa que el código compilado nativo, al estar en cache, va a tener que ser creado cada vez que se ejecute la aplicación. Esta aclaración es importante, porque algunas personas tienen la idea de que el código nativo resultante se guarda en disco (lo cual seria posible, pero no es el default).
Se podría pensar que este arreglo podria ser inclusive mas costoso que el "estilo" anterior (donde todo el código se compilaba al cargar la aplicación). Sin embargo, este costo extra no es tan grande. Y en el dado caso de que el performance sea un factor altamente determinante, existe una solución.
Existen en realidad dos "sabores" o versiones del JIT. El primero, que es el que se usa por default, no solamente realiza la compilación, sino que ademas lleva a cabo algunas optimizaciones "al vuelo", con las siguientes ventajas:
- Utilizar y alocar registros del CPU mas eficientemente
- Realizar optimizaciones de bajo nivel cuando sea necesario, como por ejemplo: propagación de la copia, eliminación de "range checking", eliminación de subexpresiones comunes, etc.
- Uso más eficiente de la memoria monitoreando la demanda actual de memoria virtual y física durante la ejecución
- Tomar ventaja del modelo exacto de procesador en uso, generando instrucciones específicas para este
Como pueden ver, este tipo de optimizaciones son las que pueden causar un "overhead" durante la ejecución. Si por alguna razón es realmente importante el performance, se puede utilizar la otra versión del JIT (la económica), la cual solamente convierte cada instrucción del MSIL a su equivalente en código nativo, sin realizar ninguna optimización.
Ahora, en caso de necesitar las optimizaciones, pero de cualquier forma querer mejorar el performance, Microsoft ofrece una solución intermedia... el llamado compilador Pre-JIT, o también conocido como "Native Image Generator" o Ngen.exe. Este se debe invocar antes del runtime, como por ejemplo durante la instalación, y va a compilar todo el código MSIL en un ensamble de código nativo en el "Global Assembly Cache", desde donde será utilizado en el futuro, brincandose toda la operación del JIT.
Aunque esto suena como la situación ideal, no debemos olvidar que el JIT realiza algunas optimizaciones basado en la demanda del sistema en ese momento en particular, como por ejemplo el uso de registros y de memoria. Al no utilizar el JIT, estamos privandonos de estas ventajas. Como en todo, la decisión final debe de ser tomada después de hacer pruebas con ambas opciones, bajo ambientes similares.
Como recomendación, se podria decir que en la mayoria de las aplicaciones, utilizar el JIT default será más que suficiente, aunque es bueno saber que se cuenta con las otras opciones, para casos extremos.
Como no quiero ser pirata, les digo que la mayor parte de esta información (incluyendo el diagrama) lo tome de este artículo.
Finalmente, solo me queda comentar que la ventaja de este modelo de compilación es que, teoricamente, si se tienen los Frameworks adecuados, el desarrollador puede escribir una aplicación solo una vez, y esta deberá correr en cualquier plataforma, es decir, en cualquier dispositivo, o en cualquier sistema operativo. Todavía no se llega a ese punto, pero es bueno saber que cuando menos las bases ya estan listas para lograr ese objetivo.
También esto significa que cualquier persona, o compañia, puede crear su propio lenguaje de programación y/o compilador, mientras siga los estandares, y será compatible con .NET. De hecho, en este artículo, se demuestra como se puede compilar desde el mismo Visual Basic.NET...
Ahora, en caso de necesitar las optimizaciones, pero de cualquier forma querer mejorar el performance, Microsoft ofrece una solución intermedia... el llamado compilador Pre-JIT, o también conocido como "Native Image Generator" o Ngen.exe. Este se debe invocar antes del runtime, como por ejemplo durante la instalación, y va a compilar todo el código MSIL en un ensamble de código nativo en el "Global Assembly Cache", desde donde será utilizado en el futuro, brincandose toda la operación del JIT.
Aunque esto suena como la situación ideal, no debemos olvidar que el JIT realiza algunas optimizaciones basado en la demanda del sistema en ese momento en particular, como por ejemplo el uso de registros y de memoria. Al no utilizar el JIT, estamos privandonos de estas ventajas. Como en todo, la decisión final debe de ser tomada después de hacer pruebas con ambas opciones, bajo ambientes similares.
Como recomendación, se podria decir que en la mayoria de las aplicaciones, utilizar el JIT default será más que suficiente, aunque es bueno saber que se cuenta con las otras opciones, para casos extremos.
Como no quiero ser pirata, les digo que la mayor parte de esta información (incluyendo el diagrama) lo tome de este artículo.
Finalmente, solo me queda comentar que la ventaja de este modelo de compilación es que, teoricamente, si se tienen los Frameworks adecuados, el desarrollador puede escribir una aplicación solo una vez, y esta deberá correr en cualquier plataforma, es decir, en cualquier dispositivo, o en cualquier sistema operativo. Todavía no se llega a ese punto, pero es bueno saber que cuando menos las bases ya estan listas para lograr ese objetivo.
También esto significa que cualquier persona, o compañia, puede crear su propio lenguaje de programación y/o compilador, mientras siga los estandares, y será compatible con .NET. De hecho, en este artículo, se demuestra como se puede compilar desde el mismo Visual Basic.NET...
0 Comments:
Post a Comment
<< Home