2012-04-25 19 views
6

Dove le istruzioni SSE di x86-64 (istruzioni vettoriali) superano le normali istruzioni. Perché quello che vedo è che i carichi e gli archivi frequenti richiesti per l'esecuzione delle istruzioni SSE stanno annullando qualsiasi guadagno che abbiamo a causa del calcolo vettoriale. Quindi qualcuno potrebbe darmi un esempio di codice SSE dove funziona meglio del normale codice.Dove le istruzioni SSE superano le normali istruzioni

La sua forse perché sto passando ogni parametro a parte, come questo ...

__m128i a = _mm_set_epi32(pa[0], pa[1], pa[2], pa[3]); 
__m128i b = _mm_set_epi32(pb[0], pb[1], pb[2], pb[3]); 
__m128i res = _mm_add_epi32(a, b); 

for(i = 0; i < 4; i++) 
po[i] = res.m128i_i32[i]; 

Non c'è un modo per passare tutti i 4 interi in una volta sola, voglio dire passare l'intero 128 byte di pa in una volta? E assegnare res.m128i_i32 a po in una volta?

+1

Fondamentalmente, ogni volta che si ha un altissimo calcolo/load-store rapporto. – Mysticial

+2

Sì, sicuramente non vuoi usare '_mm_set_epi32()' come quello. Usa '_mm_load_si128()'.E se non riesci ad allineare i dati, puoi usare '_mm_loadu_si128()' a una penalizzazione delle prestazioni. – Mysticial

+1

Allinea i dati? Cosa intendi con quello? – pythonic

risposta

10

sintesi delle osservazioni in una risposta:

Si hanno sostanzialmente caduto nella stessa trappola che cattura la maggior parte degli esordienti. Fondamentalmente ci sono due problemi nell'esempio:

  1. Si sta utilizzando in modo improprio _mm_set_epi32().
  2. Hai un rapporto di calcolo/caricamento molto basso. (1 a 3 nel tuo esempio)

_mm_set_epi32() è un prodotto molto costoso intrinseca. Sebbene sia comodo da usare, non si compila con una singola istruzione. Alcuni compilatori (come VS2010) possono generare un codice molto scadente quando si utilizza _mm_set_epi32().

Invece, dal momento che si caricano blocchi contigui di memoria, è necessario utilizzare _mm_load_si128(). Ciò richiede che il puntatore sia allineato a 16 byte. Se non è possibile garantire questo allineamento, è possibile utilizzare _mm_loadu_si128() - ma con una penalizzazione delle prestazioni. Idealmente, dovresti allineare correttamente i tuoi dati in modo da non dover ricorrere all'utilizzo di _mm_loadu_si128().


Essere veramente efficienti con SSE, si vorrà anche massimizzare il proprio rapporto di calcolo/carico-negozio. Un obiettivo che sparo è di 3 - 4 istruzioni aritmetiche per accesso alla memoria. Questo è un rapporto abbastanza alto. In genere devi rifattorizzare il codice o ridisegnare l'algoritmo per aumentarlo. La combinazione di passaggi sui dati è un approccio comune.

Lo srotolamento del loop è spesso necessario per ottimizzare le prestazioni quando si hanno corpi di grandi dimensioni con catene a dipendenza lunga.


Alcuni esempi di domande SO che utilizzano con successo SSE per ottenere l'accelerazione.

Problemi correlati