Достаточно ли безумный уровень оптимизации gcc (-O3)? - PullRequest
9 голосов
/ 23 февраля 2011

Как часть ответа на другой вопрос, я хотел показать, что безумный уровень оптимизации gcc (-O3) будет в основном отбрасывать любые переменные, которые не использовались в main.Код был:

#include <stdio.h>
int main (void) {
   char bing[71];
   int x = 7;
   bing[0] = 11;
   return 0;
}

, а вывод gcc -O3 был:

    .file "qq.c"
    .text
    .p2align 4,,15
.globl main
    .type main, @function
main:
    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret
    .size main, .-main
    .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section .note.GNU-stack,"",@progbits

Теперь я вижу, что он удалил локальные переменные, но там все еще есть немало потерь.Мне кажется, что весь раздел:

    pushl %ebp
    xorl %eax, %eax
    movl %esp, %ebp
    popl %ebp
    ret

можно заменить на более простой:

    xorl %eax, %eax
    ret

Кто-нибудь знает, почему gcc не выполняет эту оптимизацию?Я знаю, что это сэкономило бы очень мало для самого main, но, если бы это было сделано и с обычными функциями, эффект ненужной настройки указателя стека в массивном цикле был бы значительным.

Команда, используемая длясгенерировать сборку было:

gcc -O3 -std=c99 -S qq.c

Ответы [ 2 ]

9 голосов
/ 23 февраля 2011

Вы можете включить эту конкретную оптимизацию с флагом компилятора -fomit-frame-pointer.Это делает отладку невозможной на некоторых машинах и существенно более трудной для всего остального, поэтому обычно она отключается.

Хотя в документации GCC может быть сказано, что -fomit-frame-pointer включен на различных уровнях оптимизации, вы, вероятно,обнаружите, что это не так - вам почти наверняка придется явно включить его самостоятельно.

6 голосов
/ 23 февраля 2011

Включение -fomit-frame-pointer ( source ) должно избавить от лишних манипуляций со стеком.

GCC, очевидно, оставил их, потому что они облегчают отладку (получая трассировку стека при необходимости), хотя в документах отмечается, что -fomit-frame-pointer является значением по умолчанию, начиная с GCC 4.6.

...