Предоставление экземпляру класса указателя на структуру - PullRequest
1 голос
/ 11 сентября 2009

Я пытаюсь получить функциональность 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, как чумы.

Мой новый подход в основном заключается в том, чтобы данные были внешними по отношению к классу, поэтому класс не нужно выравнивать.

У меня вопрос: есть ли лучший способ получить указатель на (выровненный по памяти) экземпляр структуры или мой подход действительно тупой, и есть более чистый способ?

Ответы [ 3 ]

2 голосов
/ 11 сентября 2009

Как насчет:

__declspec( align( 16 ) ) VectorData vd;

Вы также можете создать свою собственную новую версию оператора следующим образом

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

, который затем может сделать распределение следующим образом

AlignedData* pData = new( 16 ) AlignedData;

для выравнивания на границе 16 байт.

Если это не поможет, я могу неправильно понять, о чем вы просите ...

1 голос
/ 11 сентября 2009

Вероятно, не стоит ожидать улучшения производительности для одноразовых векторов. Параллельная обработка сияет ярче, когда вы можете объединить параллельную обработку с некоторым объемом, то есть при последовательной обработке многих векторов.

0 голосов
/ 11 сентября 2009

Я исправил это. : O

Это было действительно довольно легко. Все, что мне нужно было сделать, это повернуть

VectorData* m_Point;

в

VectorData m_Point;

и мои проблемы исчезли без необходимости использовать malloc или выравнивание.

Но я ценю помощь каждого! : D

...