Che strano, non avevo mai notato randagi nop
s nell'output ASM a -O0
prima. (Probabilmente perché non sprecare il mio tempo a guardare l'output del compilatore non ottimizzato).
Solitamente le funzioni interne di nop
s sono per allineare i target di diramazione, inclusi i punti di ingresso delle funzioni come in the question Brian linked. (Vedere anche -falign-loops
in the gcc docs, che è attivo per impostazione predefinita a livelli di ottimizzazione diversi da -Os
).
In questo caso, il nop
fa parte del rumore compilatore per una funzione vuota nuda:
void go(void) {
//char name[64];
//strcpy(name, data);
}
push rbp
mov rbp, rsp
nop # only present for gcc5, not gcc 4.9.3
pop rbp
ret
See that code in the Godbolt Compiler Explorer modo da poter controllare l'ASM per altre versioni del compilatore e compilare le opzioni.
(non tecnicamente rumore, ma -O0
consente -fno-omit-frame-pointer
, ea -O0 funzioni anche vuote istituito e abbattere un frame dello stack.)
Naturalmente, che nop
non è presente in qualsiasi non- livello di ottimizzazione zero. Non c'è alcun vantaggio di debug o prestazioni per quello nop
nel codice nella domanda. (vedere i collegamenti di guida prestazioni nel x86 tag wiki, esp. Agner Fog's microarchitecture guide per conoscere ciò che rende il codice veloce sulle CPU attuali.)
La mia ipotesi è che è puramente un artefatto di interni gcc. Questo nop
è presente come nop
nell'output gcc -S
asm, non come una direttiva .p2align
. gcc non conta i byte del codice macchina, usa solo le direttive di allineamento in alcuni punti per allineare gli obiettivi importanti del ramo. Solo l'assemblatore sa quanto è veramente necessario un nop
per raggiungere l'allineamento dato.
Il valore predefinito -O0
indica a gcc che si desidera che compili velocemente e non codice buono.Ciò significa che l'output asm ti dice di più su gcc internals rispetto ad altri livelli -O
e molto poco su come ottimizzare o qualcos'altro.
Se stai cercando di imparare ASM, è più interessante guardare il codice a -Og
, ad esempio (ottimizza per il debug).
Se stai cercando di vedere quanto gcc o clang fai al codice, devi guardare -O3 -march=native
(o -O2 -mtune=intel
o qualsiasi altra configurazione con cui crei il tuo progetto). Sconcertare le ottimizzazioni fatte a -O3
è un buon modo per imparare alcuni trucchi asm, però. -fno-tree-vectorize
è utile se si desidera vedere una versione non vettoriale di qualcosa di completamente ottimizzato diverso da quello.
I NOP vengono spesso utilizzati per motivi di temporizzazione. Normalmente non è nulla di cui preoccuparsi. –
Perché dovresti preoccuparti di * timing * in quanto sopra? –
Potrebbe avere a che fare con il pipelining e gli stati di attesa? –