Pasar al contenido principal

¿Cuáles son las principales diferencias entre compiladores y emuladores?

En algunos casos, es preciso ejecutar software en un entorno diferente al que utilizamos para programar. Para ello tenemos hay varias alternativas.  Una de ellas es el uso de un compilador cruzado capaz de generar un ejecutable válido para el sistema de destino. Otra de las más populares es ejecutar el software mediante un emulador que permita reproducir las condiciones necesarias mediante software en otro entorno. Las diferencias entre compiladores y emuladores hacen que utilizar unos u otros sea más adecuado en función de cada situación y uso.

Qué es un compilador

Un compilador es un software utilizado para convertir sentencias de programación en programas ejecutables por un microprocesador. Para llevar a cabo esta tarea, el compilador analiza la sintaxis de todos los elementos del programa a compilar. Es una tarea que puede requerir diferentes pasadas hasta que el análisis se completa. En cada una de ellas se reduce el código a sus elementos más básicos. Además, se introducen optimizaciones para que su ejecución resulte tan rápida como sea posible.

Si el resultado del análisis léxico, también conocido como parseado o parseo, no es correcto, la compilación no se completará. En su lugar, se generará un mensaje de error. Si no se produce ningún error, se exportará un fichero con código intepretable por el procesador (código objeto). Sin embargo, ese código no se puede ejecutar directamente todavía. Para completar el proceso es necesario que un enlazador (linker en inglés) recopile las diferentes partes del programa, así como las librerías que se vayan a incluir en este. Una vez hecho esto, tiene que unirlas (enlazarlas) en un archivo ejecutable para el sistema operativo de destino.

En la actualidad, lenguajes como Java generan un código máquina especial conocido como bytecode. Este se puede ejecutar en diferentes entornos que dispongan del intérprete necesario. Es un punto intermedio entre los lenguajes compilados, habitualmente más rápidos en el momento de la ejecución, y los interpretados, que no necesitan compilación y por ello son más portables. Para obtener al completo las ventajas de ambos sistemas, los compiladores JIT (Just In Time) son capaces de convertir los bytecodes en código nativo. Este estará preparado para la plataforma en la que se ejecuta. Este proceso se lleva a cabo la primera vez que se ejecuta el software, de forma que en posteriores usos la ejecución resulta bastante más rápida.

Compilación cruzada

Si se desea, se puede compilar software para una arquitectura distinta a la del propio equipo en que se lleva a cabo el proceso de compilación. Esto se conoce como compilación cruzada y requiere que el sistema operativo desde el que se compila disponga de un compilador capaz de generar código para la arquitectura del procesador de destino. También de aquellas librerías necesarias para producir el programa compilado.

Este proceso cobra especial importancia cuando se compila para sistemas con menor capacidad de proceso en un PC más potente. Por ejemplo, compilar un programa para procesadores ARM puede llevar unos minutos en un PC con un procesador i7 de 8 núcleos y 16GB de memoria RAM. Hacer el mismo trabajo en un dispositivo Android o en una Raspberry Pi puede llevar varias horas.

Diferencias entre compiladores y emuladores: cuándo usar estos últimos

El caso contrario ofrece otras alternativas: si necesitamos ejecutar un programa compilado para Android o para un procesador o sistema diferente al de la máquina que estamos utilizando es posible utilizar un emulador. Este funciona de forma parecida a una máquina virtual pero, en vez de poner a disposición de la máquina virtual recursos como el procesador, reproduce fielmente el funcionamiento de este. En caso de que se trate de un sistema operativo diferente, pero dentro de la misma arquitectura, es más recomendable usar una máquina virtual.

Esto tiene una ventaja clara, que constituye una de las diferencias entre compiladores y emuladores para ejecutar software en una arquitectura diferente. Si disponemos solo de una versión ya compilada podremos también ejecutarla, e incluso podremos probar un desarrollo que estemos haciendo para otra arquitectura.

La contrapartida es, evidentemente, el rendimiento. En vez de utilizar recursos del propio hardware, el emulador reproduce por software el funcionamiento de otro procesador, lo que lo hace más lento. Volviendo al ejemplo de Android, no es un problema tan grande si la diferencia entre ambos sistemas es grande. Así, un PC de gama alta no tiene excesivos problemas en simular el funcionamiento de un procesador ARM, por lo que ejecutar Android y probar una aplicación en el emulador sin probarlo en una máquina real es una solución aceptable. Al menos, en las primeras etapas del desarrollo.

Cuándo no es recomendable usar emuladores

Por el contrario, no es recomendable utilizar de forma habitual software de emulación cuando haya una alternativa nativa. Esto se debe a otra de las diferencias entre emuladores y compiladores cruzados: los segundos permiten una mayor optimización del código para las características de cada procesador.

Si el compilador es lo bastante completo, se pueden establecer todo tipo de opciones. De esta manera, el ejecutable resultante estará tan optimizado como si se hubiese generado en el propio dispositivo con un compilador capaz de detectar todas las características del entorno en que se ejecuta.

Este aspecto puede ser importante, ya que en ocasiones es necesario generar ejecutables para distintas arquitecturas. No solo en entornos como el de los procesadores ARM, en sus diferentes versiones. También es muy habitual que el software para PC esté disponible también en versiones de 64 y 32 bits. Estas últimas, aunque cayendo rápidamente en desuso, son las únicas que se pueden utilizar en un equipo con procesador de 32 bits, o en uno de 64 bits con un sistema operativo de 32 bits.

En resumen, el uso de una u otra alternativa depende del uso que se quiera dar al software. Para desarrollar es válido cualquiera de los dos enfoques. O incluso una combinación de ambos, como hacer compilación cruzada y probar el programa nativo en un emulador. Cuando se trata de un entorno de producción, en cambio, es conveniente evitar las emulaciones en la medida de lo posible. Esto se debe a que una de las principales diferencias entre compiladores y emuladores es el rendimiento que se obtiene con cada uno de los sistemas.

Las herramientas de Go4IT que soportan los procesos de migración de los sistemas heredados están basados en tecnología de compiladores, de manera que la transformación digital no solo se limita al ahorro de licencias y costes de operación sobre plataformas mainframe, sino también la generación del nuevo sistema sobre código nativo en las plataformas escogidas.

Share this post

Comments (0)