martes, octubre 02, 2007

El futuro no es lo que solía ser (I): los lenguajes interpretados son lentos

Antes, cuando los microprocesadores eran reales y no virtuales, como ahora, el lenguaje de programación más rápido y eficiente (siempre que el n estuviese adecuadamente escrito) era C. Incluso podías contar los ciclos que tardaba una rutina en ejecutarse estimado su traducción a código máquina.

Bien queridos amiguitos esto YA NO es así. Desde que los micros llevan caches primarias secundarias y terciarias. Las instrucciones máquina son, también virtuales. Como responden los compiladores de nuestro amado C: generan código sin saber como es el micro concreto así que lo hacen para uno genérico (no hace mucho que para un 486). C++ es mucho peor. la indirección que incluye para ir a rutinas virtuales lleva a que este en bloques separados de memoria y no pueda optimizarse en tiempo de compilación, por lo que hay que borrar el pipeline y recargarlo con algo de la memoria principal.

No es así en la máquina virtual de java. Al arrancar averigua que micro tenemos (todo esos detalles que ni tu que eres el dueño del ordenador sabes) y genera código especifico a tu configuración. El resultado de esto es que si consigue que un bucle, por ejemplo, entre adecuadamente en el pipeline y la cache más interna pueda ejecutarse un par de ordenes de magnitud más rápido que otro que requiera acceder a la memoria principal

Así que ya sabéis si queréis hacer un programa rápido y eficiente usar un buen lenguaje interpretado como java.

PD: si no estáis deacuerdo o me he equivocado podéis decirmelo ehhhh..

5 comentarios:

gfunho dijo...

Y eso no depende de qué compilador y qué máquina virtual uses?

Quiero decir... no es posible compilar para un procesador específico en C? No es posible que algunas máquinas virtuales traduzcan a bytecode genérico?

De verdad Java es más rápido que C en cualquier contexto? (en sistemas empotrados ni se acerca, desde luego)

salu2 polares

Joaquín Salvachúa dijo...

El problema es que hay mas tipos de micros de los que parece. Que yo sepa no existe compilador personalizable a un micro concreto (al menos en entornos de los normales).

En entornos empotrados depende del hardware, pero si el compilador es el gcc (o un primo suyo) es mas de lo mismo.

Tampoco todas las maquinas virtuales java son la misma, pero la compilacion JIT (Just in Time) de java a partir de la 1.5 es de lo mejor que se ha realizado.

En algunos caso estaban pensando traducir no al ensamblador del microprocesador si no a las microinstrucciones del micro virtual que hay por debajo. Creo que Intel había introducido microinstrucciones muy similares a las de la máquina virtual java para ejecutarlas directamente (esto lo leí hace mucho tiempo y no me acuerdo de la referencia).

gatafunho dijo...

La verdad es que en lo que se refiere a programar para entornos normales, no tengo mucha experiencia.

Yo aportaba lo que he visto sobre todo en sistemas empotrados (teléfonos móviles con procesador ARM).

Visto lo visto, la máquina virtual de java ni se acerca al rendimiento que puedes obtener programando C, incluso aunque uses gcc para compilar a un ARM genérico. Si hablamos de usar algun compilador específico para el chipset del teléfono (todos comerciales y carísimos) el rendimiento es aún mejor.

En cualquier caso, también había oído hablar de que Java, compilado directamente a código máquina (sin máquina virtual de por medio), puede llegar a ser más rápido que Java interpretado y en algunos casos más rápido que C. Eso no choca de primeras con lo que expones?

El punto de vista que aportas, sin embargo tiene una lógica aplastante, y no me extrañaría que si en estos instantes todavía no sucede, empiece a suceder dentro de poco en cada vez más entornos.

Por otro lado, la mayoría de las aplicaciones donde la velocidad y el consumo de memoria son críticos, se sigue programando en C/C++, supongo que por la flexibilidad que te aporta en la gestión de memoria y a diversas "chapuzas" que puedes utilizar para mejorar las prestaciones.

En resumen, el entorno y el tipo de aplicación aún te guían a ir por un camino u otro pese a que un lenguaje interpretado no tiene que ser más rapido que uno compilado a código máquina.

Por cierto, soy el mismo de antes, es que blogger no me deja registrarme ahora :)

Joaquín Salvachúa dijo...

La verdad es que los moviles son como un "regreso al pasado" en cuanto micro, sistema operativo y velocidad de acceso a internet. En ellos aún aplica lo anterior... creo que ya van por potencia equivalente a un 386 o un 486 no?

gfunho dijo...

La potencia equivalente es complicada de decir. Si te puedo decir que los ultimos llevan un ARM a 330Mhz, con unidad de coma flotante y una unidad de proceso de graficos que soporta openGL directamente por hardware. Ademas todos incorporan unos cuantos chips específicos para diversas tareas (DSP´s, coprocesadores)

Por tanto si te digo que un movil es capaz de comprimir a MPEG-4 640x480pixels a 30 frames por segundo, parece una barbaridad de velocidad, pero es que lleva un chip específico que ayuda.

Desde luego, la impresión que da el rendimiento de un smartphone es la de un pentium de los antiguos :)

Como ejemplo te pongo la aplicación que desarrollo, que es capaz de generar fotografias panoramicas en tiempo real "pegando" frames de 320x240pixels a mas de 4 frames por segundo usando solo el procesador para el registro de imagenes y la interpolacion y el filtrado en las zonas comunes.

No sé si un 386 puede hacer eso así de rapido (seguramente sí), pero lo asombroso es hacerlo sin consumir apenas electricidad.

Por cierto, que el mayor problema al que se enfrentan los fabricantes de móviles es a la disipación de calor. El móvil se empieza a poner en el límite de lo que un usuario considera una temperatura "normal" para acercarse a la oreja, pese a que están lejos de chamuscártela (si no usas baterías japonesas :P)