loops assembly conditional-statements x86-64

loops - x86_64-Ensamblado-condiciones de bucle y fuera de servicio



assembly conditional-statements (1)

No estoy pidiendo un punto de referencia.

( Si ese fuera el caso, lo habría hecho yo mismo ) .

Mi pregunta:

Tiendo a evitar los modos de direccionamiento indirecto / índice por conveniencia.

Como reemplazo, a menudo uso el direccionamiento inmediato, absoluto o de registro.

El código:

; %esi has the array address. Say we iterate a doubleword (4bytes) array. ; %ecx is the array elements count (0x98767) myloop: ... ;do whatever with %esi add $4, %esi dec %ecx jnz 0x98767;

Aquí, tenemos un combo serializado (dec y jnz) que evita la ejecución fuera de orden (dependencia).

¿Hay alguna manera de evitar eso / romper el dep? (No soy un experto en ensamblaje).


Al optimizar para las CPU Intel, siempre coloque la instrucción de configuración de bandera justo antes de la instrucción de salto condicional (si es una de las simples enumeradas en la tabla a continuación), para que puedan fusionarse en una sola unidad en los decodificadores.

Hacer esto no es significativamente peor para las CPU más antiguas que no hacen macro fusión. Poner la configuración de la bandera antes podría acortar la penalización de error de predicción de la rama en uno para tales CPU, al permitir que un error de predicción se detecte antes. No tengo puntos de referencia, pero no creo que la pequeña desventaja de las CPU cada vez más raras justifique perder el beneficio de rendimiento de front-end (decodificación y problema) para las CPU que hacen fusión. El rendimiento total de UOP a menudo puede ser un cuello de botella.

AMD Bulldozer / Piledriver / Steamroller puede fusionar test/cmp con cualquier jcc , pero solo test/cmp , no cualquier otra instrucción ALU. Así que definitivamente se compara con las ramas.

De la guía de microarquitectura de Agner Fog , Tabla 9.2 (para Sandybridge / Ivybridge):

First | can pair with these | cannot pair with instruction | (and the inverse) | --------------------------------------------- cmp |jz, jc, jb, ja, jl, jg| js, jp, jo add, sub |jz, jc, jb, ja, jl, jg| js, jp, jo adc, sbb |none | inc, dec |jz, jl, jg | jc, jb, ja, js, jp, jo test | all | and | all | or, xor, not, neg | none | shift, rotate | none | Table 9.2. Instruction fusion

Básicamente, inc/dec puede fusionarse macro con un jcc siempre que la condición solo dependa de los bits modificados por inc/dec .

(De lo contrario, no se fusionan con macro, y se inserta una uop adicional para fusionar las banderas (como cuando lee eax después de escribir todo). O en CPU anteriores, una parada de banderas parciales).

Core2 / Nehalem tenía una capacidad de macro fusión más limitada (solo para CMP / TEST con combinaciones de JCC más limitadas), y Core2 no podía fusionar macro en modo de 64 bits.

Lea las guías de optimización de Asm y C de Agner Fog, si aún no lo ha hecho. Están llenos de conocimientos esenciales.