2012-02-29 29 views
5

Un argumento a favor de los lenguajes JIT como C# y Java es que pueden optimizar mejor ya que el perfilado en tiempo de ejecución de la máquina virtual puede optimizar el código mejor que el código estáticamente optimizado de C++.Una máquina virtual para C++ para optimizar el rendimiento

Sin embargo, me preguntaba si también podríamos usar una máquina virtual para optimizar el código en tiempo de ejecución para C++, o más bien cualquier lenguaje similar. Por ejemplo, podríamos tomar el IR generado por el compilador LLVM y crear una máquina virtual que interprete, JIT y optimice el código, de forma similar a como ocurre con Java y C#.

Por supuesto, no habría recolección de basura, pero el factor de optimización estaría allí. ¿Alguien ha trabajado en esto? ¿Hay documentos, herramientas sobre esto? ¿Qué tan bueno será este enfoque?

+3

[Una búsqueda en Google de "Clang" + "JIT"] (https://www.google.com/search?q=clang+jit) obtiene mucha información. – ruakh

+1

Google hace algo interesante cuando actualiza Chrome ... El programa se descompila parcialmente, de modo que se obtiene una forma algo simbólica, luego la actualización se aplica como un parche a ese formulario, y luego se compila de nuevo. Además, en los tiempos en que la gente escribía programas polimórficos que se reescribían en el tiempo de ejecución (por ejemplo, cuando detectan que una condición 'si' nunca será falsa, simplemente reemplazan la instrucción con' nop'). Entonces, no hay ninguna razón por la cual esto no debería ser factible. Ni siquiera estoy mencionando "posible", porque sabemos que ese es el caso. –

+0

De hecho, pueden optimizar mejor, pero no es así. –

Respuesta

2

En teoría, sí, se puede hacer un JIT para C++. Podría aprovechar algunas características de la arquitectura subyacente para optimizar el código agresivamente. También vendría con el inconveniente de hacer que la aplicación tarde más tiempo en cargarse en tiempo de ejecución.

Por supuesto, no habría recolección de basura y por lo tanto la sobrecarga debido a ello, pero el factor de optimización estaría allí. Tiene alguien trabajó en esto. ¿Hay documentos, herramientas sobre esto? ¿Qué tan bueno será este enfoque?

Big error aquí. La imposición de GC en general para cada tipo definido por el usuario es una sobrecarga importante. Es una de las razones por las que Android, iOS y Windows Mobile han recurrido a C/C++ para aplicaciones de alto rendimiento a pesar de haber comenzado a tratar de usar solo máquinas virtuales administradas inicialmente.

Por supuesto, el nivel adicional de direccionamiento indirecto significa que el GC es libre de hacer cosas como la memoria compacta, pero un programa C/C++ optimizado ya estaría trabajando con la memoria compactada desde el principio. También significaría que la memoria está más fragmentada inicialmente, que es un asesino de rendimiento para el tipo de aplicaciones de alto rendimiento en las que C++ es bueno (una es la que maneja búferes contiguos grandes, por ejemplo, procesamiento de video, trazado de rayos o audio tratamiento).

También convertir cada instancia de UDT en una referencia significa que todo está en el montón, lo que efectivamente está convirtiendo las operaciones que originalmente son unos pocos ciclos de reloj en cientos.

Dicho esto, para llegar al corazón de su pregunta, sin duda, el código C++ se puede generar usando JIT, pero puede que no existan razones tan convincentes para hacerlo dada la naturaleza estática en la que la gente generalmente trabaja con código C++.

+1

Al decir "No habría recolección de basura y, por lo tanto, los gastos generales debidos a ella", estoy diciendo que, dado que no habría recolección de basura, la sobrecarga sería menor. Lo lees de otra manera :)! – MetallicPriest

+0

@MetallicPriest Oh mi mal, pensé que esa oración significaba que habría gastos indirectos debido a la falta de GC. Estoy acostumbrado a que los entusiastas de C#/Java a menudo afirman que GC de alguna manera hace las cosas más rápido. Es cierto que puede compactar la memoria cuando no estamos buscando, pero uno tiene que preguntarse por qué tiene que hacer esto en primer lugar cuando, en C++, podemos simplemente crear matrices contiguas y compactas de tipos definidos por el usuario (como un matriz) desde el principio. – stinky472

4

LLVM incluye un compilador JIT, lli, y Clang ya puede producir bitcode de C++. No lo he probado, pero supongo que puede usar lli en los archivos de código de bits producidos (puede que tenga que decirle dónde encontrar los archivos lib de C++ para vincular) y JIT C++ en tiempo de ejecución. Incluso deberías poder construir el libC++ como código de bits para que también pueda ser JIT.

Google's Native Client tiene un proyecto secundario, Portable Native Client, donde creo que LLVM IR se envía al cliente, en lugar de binarios x86, para que se ajuste al cliente.

7

Este es un argumento defectuoso. Sí, las máquinas virtuales tienen más información para trabajar, pero también tienen mucho menos tiempo y espacio en comparación con los compiladores.

Además, sí, absolutamente puede hacerlo si realmente lo desea. Pero nadie lo hace, por lo que generalmente no está sucediendo.Al menos, no por razones de optimización, puede hacerlo para sandboxing.

+1

Puede precompilar C++ a bytecode como lo hace Clang, en ese punto ya puede hacer muchas optimizaciones. – Xeo

+1

@Xeo: teóricamente sí. Pero el optimizador C/C++ es bastante antiguo (en términos informáticos) y hace un trabajo relativamente bueno. Entonces, cualquier ganancia de rendimiento adicional es insignificante. Sería bueno ver a alguien publicar un artículo sobre él (tal vez lo han intentado lo encontraron infructuoso). –

Cuestiones relacionadas