Dando um exemplo de um ponteiro de classe um a um struct
-
05-07-2019 - |
Pergunta
Eu estou tentando obter a funcionalidade SSE na minha classe vetor (eu reescrito três vezes até agora:. \) E estou fazendo o seguinte:
#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
Ele funciona! Hurrah! Mas é mais lenta do que a minha tentativa anterior. Boo.
Eu já determinou que o meu gargalo é o malloc que estou usando para obter um ponteiro para um struct.
VectorData* Point3D::_NewData()
{
#if SSE_VERSION >= 2
return ((VectorData*) _aligned_malloc(sizeof(VectorData), 16));
#else
return ((VectorData*) malloc(sizeof(VectorData)));
#endif
}
Um dos principais problemas com o uso SSE em uma classe é que tem de ser alinhado na memória para que ele funcione, o que significa sobrecarregar os novos e excluir operadores, resultando em um código como este:
BadVector* test1 = new BadVector(1, 2, 3);
BadVector* test2 = new BadVector(4, 5, 6);
*test1 *= test2;
Você não pode mais usar o construtor padrão e você tem que evitar new
como a peste.
A minha nova abordagem é basicamente para ter os dados externos a partir da classe para a classe não tem que ser alinhados.
A minha pergunta é: se existe uma maneira melhor para obter um ponteiro para um (alinhado na memória) instância de um struct ou é a minha abordagem realmente estúpido e não há uma maneira mais limpa muito
Solução
Como sobre: ??
__declspec( align( 16 ) ) VectorData vd;
?
Você também pode criar sua própria versão do novo operador da seguinte forma
void* operator new( size_t size, size_t alignment )
{
return __aligned_malloc( size, alignment );
}
que pode então fazer allocationas segue
AlignedData* pData = new( 16 ) AlignedData;
para alinhar em um limite de 16 bytes.
Se isso não ajuda, então eu pode ser mal-entendido que você está pedindo para ...
Outras dicas
Você provavelmente não deve esperar para obter um melhor desempenho para vetores de uso único. processamento paralelo brilha mais quando você pode combinar o processamento paralelo com algum volume, ou seja, ao processar muitos vetores em sequência.
Eu fixo-lo. : O
Foi realmente bastante fácil. Tudo o que eu tinha a fazer era sua vez
VectorData* m_Point;
para
VectorData m_Point;
e meus problemas sumiram, sem necessidade de malloc ou alinhamento.
Mas agradeço a ajuda de todos! : D