Funzioni SIMD e matematica vettoriale

di il
7 risposte

Funzioni SIMD e matematica vettoriale

Buona sera a tutti questa è la mia prima volta che scrivo al forum. Spero di non avere sbagliato la sezione.
Come sapete da ormai un decennio le cpu supportano l'architettura SIMD che ha il grande vantaggio di pemettere le operazioni aritmetiche su dati a 128 bit; Microsoft ,naturalmente, viene in suppoto con l'header xmmintrin.h.
Da molte parti ho letto che le funzioni SIMD sono l'ideale nella grafica perchè permettono di compiere, con una sola operazione, qualsiasi funzione aritmetica su vettori fomati da 4 float (4 float=128 bit= __m128).
Su internet ho però riscontrato dei problemi riguardo l'approccio, infatti ho trovato tale codice
struct Vector4
{    
        float x, y, z, w;        
};

// Add two constant vectors and return the resulting vector
Vector4 SSE_Add ( const Vector4 &Op_A, const Vector4 &Op_B )
{
        Vector4 Ret_Vector;

        __asm 
        {        
                MOV EAX, Op_A                              // Load pointers into CPU regs
                MOV EBX, Op_B

                MOVUPS XMM0, [EAX]                 // Move unaligned vectors to SSE regs
                MOVUPS XMM1, [EBX]

                ADDPS XMM0, XMM1                   // Add vector elements
                MOVUPS [Ret_Vector], XMM0      // Save the return vector
        }

        return Ret_Vector;
}
Il problema nasce ora. Infatti il programma usa l'assembly e le istruzioni PPU, ma allora a che servono le librerie xmmintrin.h ?? a che serve il tipo __m128 se non viene usato nelle tanto osannata matematica vettoriale?? seve solo a rappresentare inutili float a 128 bit??

7 Risposte

  • Re: Funzioni SIMD e matematica vettoriale

    Guardati l'esempio MMXSwarm su MSDN sull'utilizzo delle variabili __m64 e __m128i.
  • Re: Funzioni SIMD e matematica vettoriale

    Probabilmente hai trovato degli esempi vecchi, puoi fare a meno dell' assembly, ecco un esempio:
    
    #include <xmmintrin.h>
    
    __m128 Add(__m128 a, __m128 b)
    {
    	__m128 c = _mm_add_ps(a, b);
    	return c;
    }
    
    int main()
    {
    	__m128 x = _mm_set_ps(1.1f, 2.2f, 3.3f, 4.4f);
    	__m128 y = _mm_set1_ps(0.1f);  // assegna lo stesso valore alle 4 componenti
    	
        __m128 z = _mm_setzero_ps();
    		
        z = Add(x, y);
        return 0;
    }
    
    alla fine puoi guardare il valore di z col debugger, oppure estrai le componenti.
  • Re: Funzioni SIMD e matematica vettoriale

    No ho paura che tu abbia confuso megli esempi da te proposti non c'è un esempio che usa i vettori e ne mostra l'imlementazione con le istruzioni SIMD. La mia domanda in realtà è molto più stupida di quanto si pensi...
  • Re: Funzioni SIMD e matematica vettoriale

    Ciao bisky

    Intedi dire delle classi vector del genere?
    
    class Vector4
    {   
    public:
    	__m128 m;
    };
    
    Vector4 Add(Vector4& a, Vector4& b)
    {
    	Vector4 c;
    	c.m = _mm_add_ps(a.m, b.m);
    	return c;
    }
    
    È solo per rendere l' idea, poi gli metti tutti gli operatori in overload, gli accessi tramite X, Y, Z, W ecc. ecc. O intendi qualcos' altro?
  • Re: Funzioni SIMD e matematica vettoriale

    Ciao Barba59 in effetti volevo chiederti scusa la mia prima risposta era riferita all'intervento di Skynet prima di te.
    La prima porzione di codice che mi hai postato risolve molte delel mie domande, in quanto ignoravo l'esistenza delle funzioni _mm_add_ps() e _mm_set_ps(). Auitami però a capie se ho capito. con la funzione _mm_set_ps() posso utilizzare una variabile __m128 come se fosse costituita da 4 float, e questi float possono essere sommati singolarmente con la funzione _mm_add_ps(), giusto?? inoltre esiste una funzione per accedere a un float (il primo o il secondo...) direttamente senza magheggi strani??
  • Re: Funzioni SIMD e matematica vettoriale

    Esatto, le operazioni vengono effettuate sui 4 valori separatamente. C' è anche _mm_mul_ss ecc. vedi , per assegnare i valori hai già visto _mm_set_ps.

    bisky ha scritto:


    esiste una funzione per accedere a un float (il primo o il secondo...) direttamente senza magheggi strani??
    Leggendo la documentazione su msdn parrebbe di no:
    'You should not access the __m128 fields directly. You can, however, see these types in the debugger.'

    In giro ho visto ricorrere a delle union o a cose del tipo:
    float f = ((float*)&m)[2];
  • Re: Funzioni SIMD e matematica vettoriale

    Grande ottima risposta!! il codice
     float f = ((float*)&m)[2] 
    è stranamente folle ma geniale!! non ci avrei mai pensato!!
Devi accedere o registrarti per scrivere nel forum
7 risposte