Pregunta

Estoy tratando de obtener la funcionalidad SSE en mi clase vectorial (lo he reescrito tres veces hasta ahora.: \) y estoy haciendo lo siguiente:

#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

Funciona! ¡Hurra! Pero es más lento que mi intento anterior. Boo.

He determinado que mi cuello de botella es el malloc que estoy usando para llevar el puntero a una estructura.

VectorData* Point3D::_NewData() 
{ 

#if SSE_VERSION >= 2

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

#else

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

#endif

}

Uno de los principales problemas con el uso de SSE en una clase es que debe estar alineado en la memoria para que funcione, lo que significa sobrecargar los operadores nuevos y eliminados, lo que da como resultado un código como este:

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

Ya no puedes usar el constructor predeterminado y debes evitar new como la plaga.

Mi nuevo enfoque es básicamente tener los datos externos a la clase para que la clase no tenga que estar alineada.

Mi pregunta es: ¿hay una mejor manera de obtener un puntero a una instancia (alineada en la memoria) de una estructura o mi enfoque es realmente tonto y hay una forma mucho más limpia?

¿Fue útil?

Solución

Cómo sobre: ??

__declspec( align( 16 ) ) VectorData vd;

?

También puede crear su propia versión de operador nueva de la siguiente manera

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

que luego puede hacer asignaciones como sigue

AlignedData* pData = new( 16 ) AlignedData;

para alinear en un límite de 16 bytes.

Si eso no ayuda, entonces puedo estar entendiendo mal lo que estás pidiendo ...

Otros consejos

Probablemente no debería esperar obtener un rendimiento mejorado para vectores de un solo uso. El procesamiento paralelo brilla más cuando se puede combinar el procesamiento paralelo con algún volumen, es decir, cuando se procesan muchos vectores en secuencia.

Lo arreglé. : O

Fue realmente bastante fácil. Todo lo que tenía que hacer era girar

VectorData* m_Point;

en

VectorData m_Point;

y mis problemas se han ido, sin necesidad de hacer malloc o alineación.

¡Pero aprecio la ayuda de todos! : D

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top