Domanda

sto facendo una libreria vettore / matrice. (GCC, ARM NEON, iPhone)

typedef struct{ float v[4]; } Vector;
typedef struct{ Vector v[4]; } Matrix;

I dati passata struct come puntatore per evitare di prestazioni degrado da copia dei dati quando si chiama la funzione. Così ho progettato funzione come questa in un primo momento:

void makeTranslation(const Vector* factor, Matrix* restrict result);

Ma, se la funzione è in linea, non v'è alcun motivo per passare valori come puntatore per le prestazioni? Fare quelle variabili copiati troppo? Che ne dite di registro e le cache? Ho cercato di ridisegnare funzione come questa:

inline Matrix makeTranslation(const Vector factor) __attribute__ ((always_inline));

Come pensi di chiamare i costi di ogni casi?

  • ho aggiunto 'const' al 2 firma per riflettere suggerimenti.
È stato utile?

Soluzione

Quando la funzione è in linea tipicamente Riproduzione vietata di variabili è direttamente coinvolto con la chiamata. Variabili saranno ancora essere spostate e messe in pila a volte come una parte normale di esecuzione, ma non come una conseguenza diretta della chiamata di funzione. (Quando si esegue fuori dei registri, alcuni valori possono ottenere messe in pila, ecc ... ma solo se necessario.) Così il sovraccarico della "chiamata" scompare in fondo quando è inline una funzione (non più la creazione / abbattere lo stack frame, salto incondizionato non più, non più spinta / poping parametri.)

Se si può fare affidamento sul vostro attributo always_inline a sempre inline la funzione, allora si dovrebbe anche non passare il vettore dal puntatore (se non viene modificato). La ragione di questo è che passando per puntatore richiede l'indirizzo del vettore essere presa, il che significa che il compilatore deve assicurare che esso ha un indirizzo e quindi non può esistere soltanto in registri della CPU. Questo può rallentare le cose, se non è necessario, e quando si prende l'indirizzo di qualcosa il compilatore sempre assicurarsi la disponibilità di un indirizzo perché il compilatore non può essere che l'indirizzo non è necessaria.

A causa del passaggio per puntatore, questo codice avrà sempre un'istruzione per ottenere l'indirizzo dell'oggetto, e almeno un dereference arrivare al valore di un utente. Se passate per valore, allora questo può ancora succedere, ma il compilatore può essere in grado di ottimizzare tutto questo via.

Non dimenticare che un uso eccessivo di inlining può aumentare significativamente la dimensione del codice compilatore binario. In alcuni casi hanno segmenti di codice di grandi dimensioni (come risultato di funzioni inline) può causare più cache miss istruzione con comporterà un rallentamento delle prestazioni perché la CPU è costantemente dover uscire alla memoria principale per andare a prendere le parti del programma, perché alcuni di essi è troppo grande per entrare nella piccola cache L1. Questo può essere particolarmente importante per processori embedded (come l'iPhone), perché questi processori hanno in genere piccole cache.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top