О коде x86_64, скомпилированном gcc, и оптимизации кода C

Я скомпилировал следующий код C:

typedef struct {
    long x, y, z;
} Foo;

long Bar(Foo *f, long i)
{
    return f[i].x + f[i].y + f[i].z;
}

с помощью команды gcc -S -O3 test.c. Вот функция Bar в выводе:

    .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:

У меня есть несколько вопросов об этом ассемблерном коде:

  1. Какова цель " pushq %rbp", " movq %rsp, %rbp"и" popq %rbp", если в теле функции не используются ни rbp, ни rsp?
  2. Почему rsiи rdiавтоматически содержат аргументы C-функции ( iи fсоответственно) без их чтения из стека?
  3. Я попытался увеличить размер Foo до 88 байт (11 длинныхс), и инструкция leaqстала imulq. Имеет ли смысл проектировать мои структуры так, чтобы они имели «круглые» размеры, чтобы избежать инструкций умножения (чтобы оптимизировать доступ к массиву)? Инструкция leaqзаменена на:

    imulq $88, %rsi, %rcx
    
5
задан Matt 4 June 2012 в 19:21
поделиться