2013-02-22 10 views
10

supponga Ho un'unità di compilazione costituito da tre funzioni, A, B, e C. Una volta viene invocato da una funzione esterna all'unità di compilazione (ad esempio è un punto di ingresso o callback); B è invocato molte volte da A (ad esempio è invocato in un ciclo stretto); C viene invocato una volta per ogni invocazione di B (ad esempio è una funzione di libreria).semantica di GCC attributo caldo

L'intero percorso attraverso A (passante per B e C) è critica per le prestazioni, anche se le prestazioni di un sé non è critica (come maggior parte del tempo è trascorso in B e C).

Qual è l'insieme minimo di funzioni che è necessario annotare con __attribute__ ((hot)) per eseguire un'ottimizzazione più aggressiva di questo percorso? Supponiamo di non poter utilizzare -fprofile-generate.

Equivalentemente: __attribute__ ((hot)) significa "Ottimizza il corpo di questa funzione", "Ottimizza le chiamate a questa funzione", "Ottimizza tutte le chiamate discendenti che questa funzione effettua" o una combinazione di queste?

La pagina info di GCC non affronta in modo chiaro a queste domande.

+0

'__attribute__ ((caldo))' possono ottenere voi qualcosa, ma potresti ottenere risultati migliori dal primo rendendo B e C 'statici in linea' e ottimizzando con' -O3'. – twalberg

+0

Suppongo che questi passi siano già stati presi. –

risposta

13

Official documentation:

hot L'attributo caldo su una funzione viene utilizzata per informare il compilatore che la funzione è un punto caldo del programma compilato. La funzione è ottimizzata in modo più aggressivo e su molti target è collocata in una sottosezione speciale della sezione di testo, in modo che tutte le funzioni attive appaiano vicine tra loro migliorando la località. Quando il feedback del profilo è disponibile, tramite -fprofile-use, le funzioni hot vengono rilevate automaticamente e questo attributo viene ignorato.

L'attributo caldo sulla funzione non è implementata nelle versioni GCC prima di 4.3.

L'attributo caldo su un'etichetta viene utilizzata per informare il compilatore che seguente percorso dell'etichetta sono più probabili di percorsi che non sono così annotati. Questo attributo viene utilizzato nei casi in cui non è possibile utilizzare __builtin_expect, ad esempio con goto o asm goto.

L'attributo caldo sulle etichette non è implementata nelle versioni GCC prima di 4.8.

2007:

__attribute__((hot)) 

suggerimento che la funzione contrassegnata è "caldo" e deve essere ottimizzata più aggresively e/o collocato in prossimità di altre funzioni "caldi" (per la cache frazione).

Gilad Ben-Yossef:

Come suggerisce il nome, questi attributi funzione servono accennare al compilatore che le funzioni corrispondenti sono chiamati spesso nel codice (caldo) o raramente chiamato (freddo).

Il compilatore può quindi ordinare il codice in rami, ad esempio se le istruzioni, per favorire i rami che chiamano queste funzioni a caldo e disfare funzioni funzioni a freddo, nell'ipotesi che sia più probabile che il ramo che verrà preso sarà chiamare una funzione calda e meno probabilità di chiamarne una fredda.

Inoltre, il compilatore può scegliere di raggruppare insieme le funzioni contrassegnate come hot in una sezione speciale nel file binario generato, sulla premessa che dal momento che le cache di dati e istruzioni funzionano in base alla località o la distanza relativa del codice e dei dati correlati , mettendo insieme tutte le funzioni spesso chiamate, si otterrà una migliore memorizzazione nella cache del codice per l'intera applicazione.

I buoni candidati per l'attributo hot sono funzioni fondamentali che vengono chiamate molto spesso nella base di codice. I buoni candidati per l'attributo cold sono le funzioni interne di gestione degli errori che vengono chiamate solo in caso di errori.

Così, secondo queste fonti, __attribute__ ((hot)) significa:

  • ottimizzare chiama a questa funzione
  • ottimizzare il corpo di questa funzione
  • put corpo di questa funzione per .hot sezione (per gruppo tutti gli hot code in un'unica posizione)

Dopo l'analisi del codice sorgente, possiamo dire che "caldo" l'attributo è verificato con (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl)); e quando è vero, node->frequency delle funzioni è impostato su NODE_FREQUENCY_HOT (predict.c, compute_function_frequency()).

Se la funzione ha frequenza NODE_FREQUENCY_HOT,

  • Se non ci sono informazioni sul profilo e nessun likely/unlikely sui rami, maybe_hot_frequency_p restituirà true per la funzione (==" ... FREQ frequenza è considerata sii caldo. "). Questo trasforma il valore di maybe_hot_bb_p in vero per tutti i Basic Block (BB) nella funzione ("BB può essere intensivo per la CPU e deve essere ottimizzato per le massime prestazioni.") E maybe_hot_edge_p true per tutti gli spigoli nella funzione. A sua volta in non -Os -mod, questi BB, i bordi e anche i loop saranno ottimizzati per la velocità, non per le dimensioni.

  • Per tutti i bordi delle chiamate in uscita da questa funzione, cgraph_maybe_hot_edge_p restituirà true ("Restituisce vero se la chiamata può essere calda."). Questa bandiera è utilizzata in IPA (ipa-inline.c, ipa-cp.c, ipa-inline-analysis.c) e l'influenza in linea e le decisioni di clonazione

+0

Non penso. È incompleto e sono necessari alcuni esperimenti. Penso che hot possa anche influenzare il codice, chiamato dalla funzione hot. – osgx

+1

ci si può aspettare gcc ora o in futuro per propagare l'hotness di una funzione al suo antenato e rami discendenti e le funzioni che chiamano dove gcc in grado di determinare il grafico della chiamata. – codeshot

+0

@codeshot Se questo viene fatto ciecamente a tutti gli antenati e discendenti allora la maggior parte delle volte l'intero programma viene contrassegnato come caldo, no? Anche nello scenario in cui una funzione ha più antenati e solo uno è frequentemente usato, questo sarebbe uno spreco. – Jeevaka