Comstackdor JIT contra comstackdores fuera de línea

¿Hay escenarios en los que el comstackdor JIT es más rápido que otros comstackdores como C ++?

¿Crees que en el futuro el comstackdor JIT solo verá optimizaciones menores, características pero seguirá un rendimiento similar, o habrá avances que lo harán infinitamente superior a otros comstackdores?

Parece que el paradigma de núcleos múltiples tiene alguna promesa, pero no es magia universal.

¿Alguna idea?

Sí, ciertamente hay tales escenarios.

  • La comstackción de JIT puede usar el perfil de tiempo de ejecución para optimizar casos específicos en función de la medición de las características de lo que el código realmente está haciendo en este momento, y puede recomstackr el código “activo” según sea necesario. Eso no es teórico; Java’s HotSpot realmente hace esto.
  • JITters puede optimizar la configuración específica de CPU y memoria en uso en el hardware real donde el progtwig se está ejecutando. Por ejemplo, muchas aplicaciones .NET se ejecutarán en código de 32 bits o de 64 bits, dependiendo de dónde estén JITted. En el hardware de 64 bits usarán más registros, memoria y un mejor conjunto de instrucciones.
  • Las llamadas a métodos virtuales dentro de un ciclo cerrado pueden reemplazarse por llamadas estáticas basadas en el conocimiento del tiempo de ejecución del tipo de referencia.

Creo que habrá avances en el futuro. En particular, creo que la combinación de la comstackción de JIT y el tipado dynamic mejorará significativamente. Ya estamos viendo esto en el espacio de JavaScript con V8 de Chrome y TraceMonkey. Espero ver otras mejoras de magnitud similar en un futuro no muy lejano. Esto es importante porque incluso los llamados lenguajes “estáticos” tienden a tener una serie de características dinámicas.

Sí, los comstackdores JIT pueden producir un código de máquina más rápido optimizado para el entorno actual. Pero prácticamente los progtwigs VM son más lentos que los nativos porque JITing consume tiempo (más Optimización == más tiempo), y para muchos métodos JITing puede consumir más tiempo que ejecutarlos. Y es por eso que GAC se presenta en .NET

Un efecto secundario para JITing es el gran consumo de memoria. Sin embargo, eso no está relacionado con la velocidad de cálculo, sino que puede ralentizar la ejecución del progtwig completo, ya que el consumo de memoria grande aumenta la probabilidad de que su código se pagine en el almacenamiento secundario.

Disculpa me por mi mal inglés.

JIT tiene ventajas, pero no veo que se haga cargo por completo. Los comstackdores convencionales pueden dedicar más tiempo a la optimización, mientras que un JIT necesita encontrar un equilibrio entre demasiada optimización (tomar más tiempo de lo que ahorra la optimización) y muy poco (tomar demasiado tiempo en ejecución directa).

La respuesta obvia es usar cada uno donde sea superior. Los JIT pueden aprovechar el perfilado en tiempo de ejecución más fácilmente que los optimizadores convencionales (aunque existen comstackdores que pueden tomar los perfiles de tiempo de ejecución como entrada para la optimización de la guía) y generalmente pueden hacer más optimizaciones específicas de la CPU (una vez más, los comstackdores hacen esto, pero si espera ejecutar el ejecutable en diferentes sistemas, no pueden aprovecharlo al máximo). Los comstackdores convencionales pueden pasar más tiempo y hacerlo de diferentes maneras.

Por lo tanto, el sistema de idiomas del futuro tendrá buenos comstackdores de optimización que emitirán código ejecutable diseñado para ser utilizado por buenos comstackdores JIT de optimización. (Esto también es, para muchas personas, el sistema de lenguaje del presente.) (El sistema de lenguaje del futuro también admitirá todo, desde los scripts modernos de Python / VB hasta el crujido de números de alta velocidad más feo).

Como con muchas cosas, esto fue prefigurado por Lisp. Hace bastante tiempo, algunos sistemas Lisp (no pueden decir muchos, no ha habido tantas implementaciones de Common Lisp) interpretaban las funciones de Lisp compilándolas sobre la marcha. Las expresiones S de Lisp (en qué código está escrito) son descripciones bastante sencillas de árboles de análisis sintáctico, por lo que la comstackción podría ser bastante rápida. Mientras tanto, un comstackdor Lisp de optimización podría descifrar el código donde el rendimiento era realmente importante antes de tiempo.

Básicamente, los comstackdores de JIT tienen la oportunidad de crear un perfil real de la aplicación que se está ejecutando, y hacer algunas sugerencias basadas en esa información. Los comstackdores “fuera de línea” no podrán determinar con qué frecuencia una twig salta y con qué frecuencia se produce, sin insertar un código especial, solicitan al desarrollador que ejecute el progtwig, lo ponga a prueba y recompile.

¿Por qué importa esto?

//code before if(errorCondition) { //error handling } //code after 

Se convierte en algo así como:

 //code before Branch if not error to Code After //error handling Code After: //Code After 

Y los procesadores x86 no predecirían un salto condicional en ausencia de información de la unidad de predicción de bifurcación. Eso significa que predice la ejecución del código de manejo de errores, y el procesador tendrá que vaciar la tubería cuando se dé cuenta de que la condición de error no ocurrió.

Un comstackdor JIT podría ver eso, e insertar una sugerencia para la twig, para que la CPU pueda predecir en la dirección correcta. Por supuesto, los comstackdores fuera de línea pueden estructurar el código de una manera que evitaría el error de escritura, pero si alguna vez tiene que mirar el conjunto, es posible que no le guste saltar por todas partes …

Otra cosa que se salteó en esta conversación es que cuando JIT un pedazo de código se puede comstackr a un lugar libre en la memoria. En un lenguaje como C ++ si el archivo DLL se basa de tal manera que ese trozo de memoria no está disponible, tendrá que pasar por el costoso proceso de rebase. Es más rápido JIT codificar en una dirección no utilizada luego volver a establecer una base de datos comstackda en un espacio de memoria libre. Para empeorar las cosas, una DLL rebaseada ya no se puede compartir. (vea http://msdn.microsoft.com/en-us/magazine/cc163610.aspx )

No me han impresionado mucho algunas de las optimizaciones en el código JIT de C # 3.5. Cosas simples como los movimientos de bit que son necesarios para la compresión son terriblemente ineficientes (se negó a almacenar en caché los valores en un registro de CPU y en su lugar fue a la memoria para cada operación). No sé por qué haría esto, pero hace una gran diferencia y no hay nada que pueda hacer al respecto.

Personalmente, creo que una buena solución sería un nivel de optimización (1-100) que podría establecer para decirle al comstackdor de JIT cuánto tiempo cree que debería gastar optimizando su código. La única otra solución sería un comstackdor AOT (Ahead of Time) y luego perderá muchas de las ventajas del código JIT.

Muchas personas respondieron que tal vez estoy rozando (quizás tengo el extremo equivocado) pero para mí son dos cosas diferentes:

AFAIK no hay nada que te detenga JIT’comstackdo c ++ por ejemplo proyecto código máquina Dynamo JIT:

http://arstechnica.com/reviews/1q00/dynamo/dynamo-1.html

Y realmente proporcionó mejoras de velocidad en ciertas circunstancias.

Comstackr código, en el sentido de un comstackdor de C ++, significa tomar un código escrito en un idioma y convertirlo en un conjunto de instrucciones (o en algunos casos otro idioma para comstackrlo de nuevo) que puede ser ejecutado por algún tipo de dispositivo lógico.

por ejemplo, c ++ comstackción a ensamblado (creo que 😉 o c # comstackndo a IL o comstackción de Java a código de bytes

JIT es un proceso que ocurre durante la ejecución. La máquina que ejecuta el código lo analiza para ver si puede mejorarlo. Java y C # son capaces de hacer uso de ambos a medida que el comstackdor prepara los comandos para la máquina virtual y, a continuación, la máquina virtual tiene la oportunidad, al menos, de tener otra oportunidad para optimizarla.

Algunos progtwigs no se comstackn, se interpretan, lo que significa que la máquina que los ejecuta lee el código exacto que usted escribió. Estas máquinas tienen la oportunidad de hacer JIT, pero recuerden que también pueden comstackrse estáticamente, potencialmente ser un proveedor externo en formas que el diseñador original del lenguaje nunca pensó.

Entonces, para responder a su pregunta, no creo que JIT reemplace los comstackdores estáticos. Creo que siempre habrá (siempre que haya progtwigción al menos) un lugar para tomar una representación de un progtwig y convertirlo en un conjunto de instrucciones para una máquina de algún tipo. (Posiblemente optimizando mientras lo hace)

SIN EMBARGO, creo que JIT puede convertirse en una parte más importante de la historia, a medida que evolucionan el tiempo de ejecución Java y el tiempo de ejecución de .NET. Estoy seguro de que JIT mejorará y me darán cosas como Project Dynamo. Supongo que hay margen para que el hardware tome JIT también, para que todo lo que hace su procesador se vuelva a optimizar según el entorno de tiempo de ejecución.

Los comstackdores de JIT conocen más sobre los sistemas que los comstackdores estáticos. Agregar multitheading sobre la marcha específico para la máquina puede ser una mejora de velocidad gigantesca una vez que lo ponen en funcionamiento.

Los comstackdores JIT en general tienen un poco de latencia de inicio donde la primera ejecución del progtwig / código puede ser mucho más lenta que el código precomstackdo. La desventaja del arranque en frío.

Otra gran ventaja de la comstackción de JIT es que el comstackdor se puede actualizar después de que se haya construido su progtwig y obtener nuevos trucos de comstackción sin necesidad de una nueva implementación completa del progtwig.

Una ventaja de JITing que aún no se ha mencionado es que es posible que un progtwig defina un número infinito de tipos generics. Por ejemplo:

 interface IGenericAction { bool Act(); } struct Blah { public static void ActUpon(IGenericAction action) { if (action.Act()) Blah>.ActUpon(action); } } 

Llamar a Blah.ActUpon(act) llamará a act.Act() . Si ese método devuelve verdadero, llamará a Blah>.ActUpon(act) , que a su vez llamará a act.Act>() . Si eso devuelve verdadero, se realizarán más llamadas con un tipo aún más profundamente nested. Generar código para todos los métodos de ActUpon que podrían llamarse sería imposible, pero afortunadamente no es necesario. Los tipos no necesitan ser generados hasta que sean usados. Si action>.Act() devuelve false, luego Blah>.ActUpon no llamará a Blah>.ActUpon y el último tipo no necesitarán ser creados.

Un punto aún no mencionado que favorece a los comstackdores “fuera de línea” es que tales comstackdores pueden ser útiles para plataformas con pequeñas cantidades de RAM, incluso tan solo dieciséis BYTES. Para estar seguro, todo lo que sea remotamente compatible con PC es capaz de tener (literalmente) millones de veces más RAM que eso, pero creo que pasará un tiempo antes de que uno pueda encontrar una máquina con muchos megas de RAM que cueste menos de $ 0.50 y consum menos de un milivatio de potencia durante la operación.

Tenga en cuenta que los 16 bytes de RAM no son tan débiles como parece, ya que los chips con una RAM tan pequeña no almacenan código en la memoria RAM: tienen un área de memoria no volátil separada para contener el código (384 bytes es el el más pequeño que conozco). Eso no es mucho, por supuesto, pero es suficiente para permitir que un procesador de $ 0.25 realice funciones que de otra manera requerirían un valor de $ 1.00 en componentes discretos.

Los comstackdores de JIT tienen más datos que pueden usar para influir en las optimizaciones. Por supuesto, alguien tiene que escribir código para usar esa información, así que no es tan simple.