Sì, ma avrà l'effetto no. Le eccezioni sono architetture obsolete (obsolete) pre Netburst, e anche allora non fa nulla di misurabile.
C'è un opcode "suggerimento ramo" introdotto da Intel con l'architettura Netburst e una previsione di ramo statica predefinita per salti a freddo (previsione anticipata all'indietro, previsione anticipata non eseguita) su alcune architetture meno recenti. GCC implementa questo con __builtin_expect (x, prediction)
, in cui la previsione è in genere 0 o 1. Il codice operativo emesso dal compilatore è ignorato su tutte le più recenti architetture di processore (> = Core 2). Il piccolo caso d'angolo in cui questo effettivamente fa qualcosa è il caso di un salto freddo sulla vecchia architettura Netburst. Intel consiglia ora di non utilizzare i suggerimenti di derivazione statica, probabilmente perché considerano l'aumento delle dimensioni del codice più dannoso rispetto alla possibile accelerazione marginale.
Oltre al suggerimento di ramo inutile per il predittore, __builtin_expect
ha il suo uso, il compilatore può riordinare il codice per migliorare l'utilizzo della cache o per risparmiare memoria.
Ci sono diversi motivi per cui non funziona come previsto.
- Il processore è in grado di prevedere piccoli cicli (n. < 64) perfettamente.
- Il processore può prevedere perfettamente i piccoli motivi ripetuti (n ~ 7).
- Il processore stesso può stimare la probabilità di un ramo durante l'esecuzione migliore del compilatore/programmatore durante la compilazione.
- La prevedibilità (= probabilità che un ramo venga previsto correttamente) di un ramo è molto più importante della probabilità che il ramo venga prelevato. Sfortunatamente questo è altamente dipendente dall'architettura e il predire la prevedibilità del ramo è notoriamente difficile.
Maggiori informazioni sui lavori interni della previsione ramo di Agner Fogs manuals. Vedere anche gcc mailing list.
Compilare con profilo Guided Optimization (-fprofile-generare, eseguito su alcuni dati di test, -fprofile-uso). Quindi gcc conoscerà le statistiche per ogni ramo e sarà in grado di disporre il codice in modo ottimale per il percorso veloce. Ma builtin_expect è ancora una buona idea per i luoghi in cui sarà utile, nel caso in cui il codice sia compilato senza PGO. Il kernel Linux ha alcune buone macro (ad esempio, probabile() e improbabile()) per questo, dal momento che è difficile generare dati di profilo per un kernel. –
MS fornisce PGO, come pure - http://blogs.msdn.com/vcblog/archive/2008/11/12/pogo.aspx. –