compilé el siguiente código C:Acerca del código compilado gcc-x86_64 y optimización de código C
typedef struct {
long x, y, z;
} Foo;
long Bar(Foo *f, long i)
{
return f[i].x + f[i].y + f[i].z;
}
con el comando gcc -S -O3 test.c
. Esta es la función de la barra en la salida:
.section __TEXT,__text,regular,pure_instructions
.globl _Bar
.align 4, 0x90
_Bar:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
leaq (%rsi,%rsi,2), %rcx
movq 8(%rdi,%rcx,8), %rax
addq (%rdi,%rcx,8), %rax
addq 16(%rdi,%rcx,8), %rax
popq %rbp
ret
Leh_func_end1:
Tengo algunas preguntas acerca de este código de montaje:
- ¿Cuál es el propósito de "
pushq %rbp
", "movq %rsp, %rbp
", y "popq %rbp
", si no se usarbp
nirsp
en el cuerpo de la función? - ¿Por qué
rsi
yrdi
contienen automáticamente los argumentos para la función C (i
yf
, respectivamente) sin leerlos de la pila? Intenté aumentar el tamaño de Foo a 88 bytes (11
long
s) y la instrucciónleaq
se convirtió enimulq
. ¿Tendría sentido diseñar mis estructuras para tener tamaños "redondos" para evitar las instrucciones de multiplicación (para optimizar el acceso a la matriz)? La instrucciónleaq
fue sustituido por:imulq $88, %rsi, %rcx
He publicado el código que obtuve. – Matt
Sí, sé todo eso. Mi pregunta es si vale la pena rellenar la estructura con espacio adicional solo para que sea un número "redondo" (como 12 largos en lugar de 11 largos) lo que evitaría usar una multiplicación al calcular el índice de matriz. – Matt
@Matt: nadie puede responder que, en general, el relleno no viene gratis (tamaños de caché); no adivinen, midan! – Christoph