Sto lavorando su tecniche di ottimizzazione eseguite dal compilatore Native .Net. Ho creato un loop del campione:Perché. Native compile loop in ordine inverso?
for (int i = 0; i < 100; i++)
{
Function();
}
E ho compilato con nativo. Quindi ho disassemblato il file .dll
con codice macchina all'interno di IDA. Come risultato, ho:
(ho rimosso poche righe non necessarie, quindi non preoccupatevi che le linee indirizzo sono inconsistant)
Capisco che add esi, 0FFFFFFFFh
significa veramente subtract one from esi and alter Zero Flag if needed
, così possiamo saltare all'inizio se zero non è stato ancora raggiunto.
Quello che non capisco è perché il compilatore ha eseguito il ciclo?
Sono venuto a conclusione che
LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
è solo più veloce rispetto ad esempio
LOOP:
inc esi
cmp esi, 064h
jl LOOP
Ma è proprio a causa di questo ed è la differenza di velocità davvero significativo?
AGGIUNGI con un valore immediato è più veloce di INC e salti anche CMP ... tutto in 3 righe di codice. Allora sì, la differenza è DAVVERO significativa (sia per dimensioni che per velocità). Immagina di farlo in ~ 30000 posti in un programma del mondo reale ... –
Sì, è più veloce, e in generale gli ottimizzatori applicheranno qualsiasi ottimizzazione possibile che renda il tuo codice più veloce senza cambiare la semantica del tuo programma. –
Per quanto riguarda la direzione invertita, forse il confronto con lo zero è più veloce del confronto con un valore specifico? – user5226582