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

Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top