2016-06-05 38 views
24

Rust ha un attributo "in linea" che può essere utilizzato in uno di questi tre gusti:Quando deve essere usato in linea in Rust?

#[inline]

#[inline(always)]

#[inline(never)]

Quando dovrebbero essere usati?

Nel riferimento Rust, vediamo an inline attributes section dicendo

Il compilatore inline automaticamente le funzioni base di euristiche interne. Le funzioni di inlining in modo errato possono effettivamente rallentare il programma, quindi dovrebbe essere usato con attenzione.

Nel forum di Rust internals, huon era anche conservative about specifying inline.

Ma vediamo considerable usage nella sorgente di Ruggine, inclusa la libreria standard. Molti attributi inline vengono aggiunti alle funzioni a una riga, che dovrebbero essere facili da individuare e ottimizzare per i compilatori tramite l'euristica in base al riferimento. Sono quelli che in realtà non sono necessari?

risposta

27

Una limitazione dell'attuale compilatore Rust è che, se non si utilizza LTO (Link-Time Optimization), non verrà mai in linea una funzione non contrassegnata #[inline] attraverso le casse. Rust utilizza un modello di compilazione separato simile a C++, in quanto l'implementazione LTO di LLVM non si adatta bene ai progetti di grandi dimensioni. Pertanto, le piccole funzioni esposte ad altre casse devono essere contrassegnate a mano. Questa non è una grande situazione, ed è probabile che venga risolta in futuro grazie a una combinazione di miglioramenti apportati all'integrazione di LTO e MIR.

#[inline(never)] è talvolta utile per il debug (separando un pezzo di codice che non funziona come previsto). In teoria, può essere usato per il benchmarking, ma di solito è una cattiva idea: disattivando l'inlining non si impediscono altre ottimizzazioni inter-procedurali come la propagazione costante. In termini di codice normale, può ridurre la codifica se si dispone di una funzione di supporto utilizzata di frequente che viene utilizzata solo per la gestione degli errori.

#[inline(always)] è generalmente una cattiva idea; se una funzione è abbastanza grande che il compilatore non la in linea per impostazione predefinita, è abbastanza grande che il sovraccarico della chiamata non è rilevante (e l'inlining eccessivo aumenta la pressione della cache delle istruzioni). Ci sono delle eccezioni, ma hai bisogno di misurazioni delle prestazioni per giustificarlo. https://github.com/rust-lang/rust/commit/274bb24efdbeed0ab1a91f3c02f86551ef16eac7 è il tipo di situazione in cui vale la pena considerare. #[inline(always)] può anche essere utilizzato per migliorare la qualità del codice -00, ma di solito non vale la pena preoccuparsi.

+5

nota che 'inline (never)' viene utilizzato sull'intrins del panico per assicurarsi che l'ottimizzatore non funzioni inline che vengono chiamate solo nel caso di panico. –