tipos procesadores procesador microprocesador funciona funcion como central performance assembly alignment x86-64

performance - microprocesador - procesadores intel



¿Cuánto realmente importa la alineación de funciones en los procesadores modernos? (1)

TL; DR : la alineación de la caché es importante. No quieres bytes que no ejecutarás.

Al menos, querrás evitar ir a buscar las instrucciones antes de la primera que ejecutarás. Como se trata de un microensayo de referencia, lo más probable es que no vea ninguna diferencia, pero imagínese en un programa completo, si tiene un error de caché adicional en un conjunto de funciones porque el primer byte no estaba alineado con un caché. línea y finalmente tuvo que buscar una nueva línea de caché para los últimos N bytes de la función (donde N <= el número de bytes antes de la función que almacenó en caché pero no utilizó).

El manual de optimización de Intel dice esto:

3.4.1.5 Alineación de código

La disposición cuidadosa del código puede mejorar la ubicación de la memoria caché y la memoria. Probables secuencias de bloques básicos deben establecerse contiguamente en la memoria. Esto puede implicar la eliminación de código improbable, como el código para manejar las condiciones de error, de la secuencia. Consulte la Sección 3.7, "Prefetching", sobre la optimización del captador previo de instrucciones.

3-8 CodAssembly / Compiler Coding Rule 12. (M impact, H generality) Todos los branch targets deben estar alineados en 16 bytes.

Ensamblaje / Compilación Codificación Regla 13. (M impacto, H generalidad) Si el cuerpo de un condicional no es probable que se ejecute, debe colocarse en otra parte del programa. Si es muy poco probable que se ejecute y la ubicación del código es un problema, debe colocarse en una página de códigos diferente.

También ayuda a explicar por qué no nota ninguna diferencia en su programa. Todo el código se almacena en caché una vez y nunca abandona el caché (modulo context-switches, por supuesto).

Cuando compilo el código C con un compilador reciente en un sistema amd64 o x86, las funciones se alinean a un múltiplo de 16 bytes. ¿Cuánto realmente importa esta alineación en los procesadores modernos? ¿Hay una gran penalización de rendimiento asociada con llamar a una función desalineada?

Punto de referencia

Ejecuté el siguiente microbenchmark ( call.S ):

// benchmarking performance penalty of function alignment. #include <sys/syscall.h> #ifndef SKIP # error "SKIP undefined" #endif #define COUNT 1073741824 .globl _start .type _start,@function _start: mov $COUNT,%rcx 0: call test dec %rcx jnz 0b mov $SYS_exit,%rax xor %edi,%edi syscall .size _start,.-_start .align 16 .space SKIP test: nop rep ret .size test,.-test

con el siguiente script de shell:

#!/bin/sh for i in `seq 0 15` ; do echo SKIP=$i cc -c -DSKIP=$i call.S ld -o call call.o time -p ./call done

En una CPU que se identifica a sí misma como CPU Intel (R) Core (TM) i7-2760QM a 2.40 GHz según /proc/cpuinfo . El desplazamiento no hizo una diferencia para mí, el punto de referencia tomó constante 1.9 segundos para ejecutarse.

Por otro lado, en otro sistema con una CPU que se informa a sí misma como una CPU Intel (R) Core (TM) i7 L 640 @ 2.13GHz , el índice de referencia toma 6,3 segundos, excepto si tiene un desplazamiento de 14 o 15, donde el código toma 7.2 segundos. Creo que es porque la función comienza a abarcar múltiples líneas de caché.