Domanda

Uso ampiamente la matematica 3D nella mia applicazione. Quanta velocità posso ottenere convertendo la mia libreria di vettori / matrici in SSE, AltiVec o un codice SIMD simile?

È stato utile?

Soluzione

Nella mia esperienza, di solito vedo un miglioramento 3x nel prendere un algoritmo da x87 a SSE e un migliore rispetto al miglioramento 5x nel passaggio a VMX / Altivec (a causa di problemi complicati che hanno a che fare con profondità della pipeline, programmazione, ecc.). Ma di solito lo faccio solo nei casi in cui ho centinaia o migliaia di numeri su cui operare, non per quelli in cui sto facendo un vettore alla volta ad hoc.

Altri suggerimenti

Non è tutta la storia, ma è possibile ottenere ulteriori ottimizzazioni usando SIMD, dai un'occhiata alla presentazione di Miguel su quando ha implementato le istruzioni SIMD con MONO che ha tenuto su PDC 2008 ,

 SIMD batte il culo di doppio in questa particolare configurazione.
(fonte: tirania.org )

Immagine dal post del blog di Miguel.

Per alcuni numeri molto approssimativi: ho sentito alcune persone su ompf.org rivendicare 10 volte accelerazioni per qualche mano routine di ray tracing ottimizzate. Ho anche avuto delle buone accelerazioni. Stimo di essere arrivato tra la 2x e la 6x sulla mia routine a seconda del problema, e molti di questi avevano un paio di depositi e carichi inutili. Se hai una grande quantità di diramazioni nel tuo codice, dimenticalo, ma per problemi che sono naturalmente paralleli ai dati puoi fare abbastanza bene.

Tuttavia, dovrei aggiungere che i tuoi algoritmi dovrebbero essere progettati per l'esecuzione in parallelo di dati. Ciò significa che se hai una libreria matematica generica come hai già detto, dovrebbero essere necessari vettori pieni piuttosto che singoli vettori o perderai semplicemente il tuo tempo.

es. Qualcosa come

namespace SIMD {
class PackedVec4d
{
  __m128 x;
  __m128 y;
  __m128 z;
  __m128 w;

  //...
};
}

La maggior parte dei problemi in cui le prestazioni contano possono essere parallelizzate poiché molto probabilmente lavorerai con un set di dati di grandi dimensioni. Il tuo problema mi sembra un caso di ottimizzazione prematura per me.

Per le operazioni 3D, fai attenzione ai dati non inizializzati nel tuo componente W. Ho visto casi in cui le operazioni SSE (_mm_add_ps) impiegavano 10 volte il normale tempo a causa di dati errati in W.

La risposta dipende fortemente da cosa sta facendo la libreria e da come viene utilizzata.

I guadagni possono andare da pochi punti percentuali, a "molte volte più velocemente", le aree più suscettibili di vedere guadagni sono quelle in cui non hai a che fare con vettori o valori isolati, ma più vettori o valori che devono essere elaborato allo stesso modo.

Un'altra area è quando si raggiungono limiti di cache o di memoria, che, ancora una volta, richiedono l'elaborazione di molti valori / vettori.

I domini in cui i guadagni possono essere i più drastici sono probabilmente quelli dell'elaborazione di immagini e segnali, simulazioni computazionali, nonché operazioni matematiche 3D generali su mesh (piuttosto che vettori isolati).

Al giorno d'oggi tutti i buoni compilatori per x86 generano istruzioni SSE per la matematica mobile SP e DP per impostazione predefinita. È quasi sempre più veloce usare queste istruzioni rispetto a quelle native, anche per operazioni scalari, purché le pianifichi correttamente. Questo sarà una sorpresa per molti, che in passato hanno scoperto che SSE era "lento", e pensavano che i compilatori non potessero generare istruzioni scalari SSE veloci. Ma ora, devi usare un interruttore per disattivare la generazione SSE e usare x87. Si noti che x87 è effettivamente deprecato a questo punto e potrebbe essere rimosso completamente dai futuri processori. L'unico aspetto negativo di questo è che potremmo perdere la capacità di fare il float DP a 80 bit nel registro. Ma il consenso sembra essere se dipendi da float DP a 80 bit anziché a 64 bit per la precisione, dovresti cercare un algoritmo più tollerante alla perdita di precisione.

Tutto quanto sopra è stato per me una completa sorpresa. È molto intuitivo. Ma i dati parlano.

Molto probabilmente vedrai solo un'accelerazione molto piccola, se presente, e il processo sarà più complicato del previsto. Per maggiori dettagli vedi La classe di vettore Ubiquitous SSE di Fabian Giesen.

  

La classe vettoriale SSE Ubiquitous: sfatare un mito comune

     

Non così importante

     

Innanzitutto, la tua classe vettoriale probabilmente non è così importante per le prestazioni del tuo programma come pensi (e, se lo è, è più probabile perché stai facendo qualcosa di sbagliato che perché i calcoli sono inefficienti). Non fraintendetemi, probabilmente sarà una delle lezioni più utilizzate nell'intero programma, almeno quando si fa grafica 3D. Ma solo perché le operazioni vettoriali saranno comuni non significa automaticamente che domineranno il tempo di esecuzione del tuo programma.

     

Non così caldo

     

Non facile

     

Non ora

     

Non mai

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