GCC добавляет странные временные переменные - PullRequest
0 голосов
/ 28 октября 2011

Я создал этот код:

#include <stdio.h>

typedef unsigned int uint;
uint in[2]={1,2},out[2]={3,4};

int main() {

    in[0]=out[0]/10;
}

и скомпилировал его с GCC (v4.4.5, без оптимизаций) в Linux, получившаяся сборка:

0000000000400474 <main>:
400474:       55                      push   rbp
400475:       48 89 e5                mov    rbp,rsp
400478:       8b 05 ae 03 20 00       mov    eax,DWORD PTR [rip+0x2003ae]        # 0082c <out>
40047e:       89 45 fc                mov    DWORD PTR [rbp-0x4],eax
400481:       ba cd cc cc cc          mov    edx,0xcccccccd
400486:       8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]
400489:       f7 e2                   mul    edx
40048b:       89 d0                   mov    eax,edx
40048d:       c1 e8 03                shr    eax,0x3
400490:       89 05 8e 03 20 00       mov    DWORD PTR [rip+0x20038e],eax        # 600824 <in>
400496:       c9                      leave
400497:       c3                      ret
400498:       90                      nop
400499:       90                      nop
40049a:       90                      nop
40049b:       90                      nop
40049c:       90                      nop
40049d:       90                      nop
40049e:       90                      nop
40049f:       90                      nop

Теперь возникает вопрос: что этот код делает в строке # 5?

40047e:       89 45 fc                mov    DWORD PTR [rbp-0x4],eax

не хранится ли значение, полученное из out [0], снова в каком-то месте в памяти? Почему так? Я не сказал ему читать и писать сразу в какое-то место.

Теперь эта временная переменная снова появляется по адресу 400486 в строке № 7:

400486:       8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]

Похоже, что в этом примере GCC создает очень неэффективный код и из-за этих временных хранилищ вытеснит строку кэша. Пожалуйста, подтвердите, может быть, я что-то не понимаю.

1 Ответ

5 голосов
/ 28 октября 2011

GCC делает очень неэффективный код при компиляции на -O0 - то, что вы видите, это в основном грубый перевод его внутреннего представления программы. Это внутреннее представление включает в себя ряд временных переменных, и ваша пара загрузки / сохранения здесь представляет собой значение, проходящее через такую ​​временную переменную. На более высоких уровнях оптимизации эти виды бесполезных нагрузок / магазинов будут в основном устранены; однако на -O0 отключен даже самый простой анализ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...