Я пытаюсь получить функциональность SSE в своем векторном классе (пока я переписывал его три раза.: \), И я делаю следующее:
#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
Это работает! Ура! Но это медленнее, чем моя предыдущая попытка. Boo.
Я определил, что моя горловина бутылки - это malloc, который я использую для получения указателя на структуру.
VectorData* Point3D::_NewData()
{
#if SSE_VERSION >= 2
return ((VectorData*) _aligned_malloc(sizeof(VectorData), 16));
#else
return ((VectorData*) malloc(sizeof(VectorData)));
#endif
}
Одной из основных проблем использования SSE в классе является то, что он должен быть выровнен в памяти, чтобы он работал, что означает перегрузку операторов new и delete, что приводит к коду, подобному этому:
BadVector* test1 = new BadVector(1, 2, 3);
BadVector* test2 = new BadVector(4, 5, 6);
*test1 *= test2;
Вы больше не можете использовать конструктор по умолчанию, и вам нужно избегать new
, как чумы.
Мой новый подход в основном заключается в том, чтобы данные были внешними по отношению к классу, поэтому класс не нужно выравнивать.
У меня вопрос: есть ли лучший способ получить указатель на (выровненный по памяти) экземпляр структуры или мой подход действительно тупой, и есть более чистый способ?