Dirección de las etiquetas (MSVC)


Estamos escribiendo un código de bytes para un lenguaje compilado de alto nivel, y después de un poco de perfilado y optimización, quedó claro que la sobrecarga de rendimiento más grande actual es la instrucción switch que estamos usando para saltar a los casos de código de bytes.

Investigamos extrayendo la dirección de cada etiqueta de caso y almacenándola en el flujo de código de bytes en sí, en lugar del ID de instrucción que generalmente encendemos. Si hacemos eso, podemos saltar la tabla de salto, y saltar directamente a la ubicación del código de la instrucción actualmente en ejecución. Esto funciona fantásticamente en GCC, sin embargo, MSVC no parece soportar una característica como esta.

Intentamos usar inline assembly para agarrar la dirección de las etiquetas (y saltar a ellas), y funciona, sin embargo, usar inline assembly hace que el optimizador MSVC evite toda la función.

¿Hay alguna forma de permitir que el optimizador siga ejecutándose sobre el código? Desafortunadamente, no podemos extraer el ensamblaje en línea en otra función que no sea la que se hicieron las etiquetas, ya que no hay manera de hacer referencia a una etiqueta para otra función, incluso en el ensamblaje en línea. Cualquier idea o ideas? Su aportación es muy apreciada, gracias!

Author: Deduplicator, 2011-06-21

3 answers

La única manera de hacer esto en MSVC es usando el ensamblaje en línea (que básicamente te fastidia para x64):

int _tmain(int argc, _TCHAR* argv[])
{
case_1:
    void* p;
    __asm{ mov [p],offset case_1 }
    printf("0x%p\n",p);
    return 0;
}

Si planea hacer algo como esto, entonces la mejor manera sería escribir todo el intérprete en assembly y luego vincularlo al binario principal a través del enlazador (esto es lo que hizo LuaJIT, y es la razón principal por la que la VM es tan cegadoramente rápida, cuando no está ejecutando código JIT'ed que es).

LuaJIT es de código abierto , por lo que podría recoger algunos consejos de él si vas por esa ruta. Alternativamente, es posible que desee buscar en la fuente de forth (cuyo creador desarrolló el principio que está tratando de usar), si hay una compilación de MSVC, puede ver cómo lo lograron, de lo contrario, está atascado con GCC (que no es una mala cosa, funciona en todas las plataformas principales).

 15
Author: Necrolis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-15 10:44:20

Echa un vistazo a lo que Erlang hace para construir en Windows. Usan MSVC para la mayor parte de la compilación, y luego GCC para un archivo para hacer uso de la extensión labels-as-values. El código objeto resultante es entonces hackeado para ser compatible con el enlazador MSVC.

Http://www.erlang.org/doc/installation_guide/INSTALL-WIN32.html

 10
Author: goertzenator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-03 15:17:57

Parece que solo podría mover el código real a funciones, en lugar de etiquetas de mayúsculas y minúsculas. El código de bytes se puede transformar trivialmente en llamadas directas. Es decir, el código de bytes 1 se traduciría a CALL BC1. Dado que estás generando llamadas directas, no tienes la sobrecarga de punteros de función. Las tuberías de la mayoría de las CPU pueden seguir tales ramas directas incondicionales.

Como resultado, las implementaciones reales de cada código de byte se optimizan, y la conversión de código de byte a código machince es una conversión trivial 1:1. Se obtiene un poco de expansión de código ya que cada CALL es de 5 bytes (suponiendo x86-32), pero es poco probable que sea un problema importante.

 3
Author: MSalters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-15 07:47:53