Предоставление экземпляру класса указателя на структуру

StackOverflow https://stackoverflow.com/questions/1411222

Вопрос

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

Это работает!Ура!Но это медленнее, чем моя предыдущая попытка.Бу.

Я определил, что мое бутылочное горлышко - это 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 как от чумы.

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

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

Это было полезно?

Решение

Как насчет:

__declspec( align( 16 ) ) VectorData vd;

?

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

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

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

AlignedData* pData = new( 16 ) AlignedData;

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

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

Другие советы

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

Я все починил.:O

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

VectorData* m_Point;

в

VectorData m_Point;

и мои проблемы исчезли, больше не нужно использовать malloc или выравнивание.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top