Domanda

Sto cercando di ottenere la funzionalità SSE nella mia classe vettoriale (l'ho riscritta tre volte finora.: \) e sto facendo quanto segue:

#ifndef _POINT_FINAL_H_
#define _POINT_FINAL_H_

#include "math.h"

namespace Vector3D
{

#define SSE_VERSION 3

#if SSE_VERSION >= 2

    #include <emmintrin.h>  // SSE2

    #if SSE_VERSION >= 3

        #include <pmmintrin.h>  // SSE3

    #endif

#else

#include <stdlib.h>

#endif

#if SSE_VERSION >= 2

    typedef union { __m128 vector; float numbers[4]; } VectorData;
    //typedef union { __m128 vector; struct { float x, y, z, w; }; } VectorData;

#else

    typedef struct { float x, y, z, w; } VectorData;

#endif

class Point3D
{

public:

    Point3D();
    Point3D(float a_X, float a_Y, float a_Z);
    Point3D(VectorData* a_Data);
    ~Point3D();

    // a lot of not-so-interesting functions

private:

    VectorData* _NewData();

}; // class Point3D

}; // namespace Vector3D

#endif

Funziona! Evviva! Ma è più lento del mio precedente tentativo. Boo.

Ho determinato che il mio collo di bottiglia è il malloc che sto usando per ottenere un puntatore a una struttura.

VectorData* Point3D::_NewData() 
{ 

#if SSE_VERSION >= 2

    return ((VectorData*) _aligned_malloc(sizeof(VectorData), 16)); 

#else

    return ((VectorData*) malloc(sizeof(VectorData))); 

#endif

}

Uno dei principali problemi con l'utilizzo di SSE in una classe è che deve essere allineato in memoria affinché funzioni, il che significa sovraccaricare i nuovi operatori ed eliminare, con conseguente codice come questo:

 BadVector* test1 = new BadVector(1, 2, 3);
 BadVector* test2 = new BadVector(4, 5, 6);
 *test1 *= test2;

Non puoi più usare il costruttore predefinito e devi evitare new come la peste.

Il mio nuovo approccio è sostanzialmente quello di avere i dati esterni alla classe in modo che la classe non debba essere allineata.

La mia domanda è: c'è un modo migliore per ottenere un puntatore a un'istanza (allineata sulla memoria) di una struttura o il mio approccio è davvero stupido e c'è un modo molto più pulito?

È stato utile?

Soluzione

Che ne dici di:

__declspec( align( 16 ) ) VectorData vd;

Puoi anche creare la tua nuova versione dell'operatore come segue

void* operator new( size_t size, size_t alignment )
{
     return __aligned_malloc( size, alignment );
}

che può quindi effettuare le allocazioni come segue

AlignedData* pData = new( 16 ) AlignedData;

per allinearsi ad un limite di 16 byte.

Se questo non è di aiuto, allora potrei fraintendere quello che stai chiedendo ...

Altri suggerimenti

Probabilmente non dovresti aspettarti di migliorare le prestazioni per i vettori monouso. L'elaborazione parallela brilla di più quando è possibile combinare l'elaborazione parallela con un certo volume, vale a dire quando si elaborano molti in sequenza.

L'ho risolto. : O

È stato davvero piuttosto semplice. Tutto quello che dovevo fare era girare

VectorData* m_Point;

in

VectorData m_Point;

e i miei problemi sono spariti, senza bisogno di malloc o allineamento.

Ma apprezzo l'aiuto di tutti! : D

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