Question

J'essaie d'obtenir la fonctionnalité SSE dans ma classe de vecteurs (je l'ai réécrite trois fois jusqu'à présent.: \) et je procède comme suit:

#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

Cela fonctionne! Hourra! Mais c'est plus lent que ma précédente tentative. Boo.

J'ai déterminé que mon goulot de bouteille était le malloc que j'utilise pour obtenir un pointeur sur une structure.

VectorData* Point3D::_NewData() 
{ 

#if SSE_VERSION >= 2

    return ((VectorData*) _aligned_malloc(sizeof(VectorData), 16)); 

#else

    return ((VectorData*) malloc(sizeof(VectorData))); 

#endif

}

L’un des principaux problèmes liés à l’utilisation de SSE dans une classe est qu’elle doit être alignée en mémoire pour fonctionner, ce qui implique de surcharger les nouveaux opérateurs et les opérateurs de suppression, ce qui entraîne un code comme celui-ci:

 BadVector* test1 = new BadVector(1, 2, 3);
 BadVector* test2 = new BadVector(4, 5, 6);
 *test1 *= test2;

Vous ne pouvez plus utiliser le constructeur par défaut et vous devez éviter new comme le fléau.

Ma nouvelle approche consiste essentiellement à avoir les données externes à la classe afin que celle-ci n'ait pas à être alignée.

Ma question est la suivante: existe-t-il un meilleur moyen d'obtenir un pointeur sur une instance (alignée sur la mémoire) d'une structure ou mon approche est-elle vraiment idiote et la méthode est-elle beaucoup plus propre?

Était-ce utile?

La solution

Que diriez-vous de:

__declspec( align( 16 ) ) VectorData vd;

?

Vous pouvez également créer votre propre version de l'opérateur new comme suit

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

qui peut ensuite faire une allocation comme suit

AlignedData* pData = new( 16 ) AlignedData;

pour aligner sur une limite de 16 octets.

Si cela ne vous aide pas, je risque de ne pas comprendre ce que vous demandez ...

Autres conseils

Vous ne devriez probablement pas vous attendre à de meilleures performances pour les vecteurs à usage unique. Le traitement en parallèle est plus brillant lorsque vous pouvez combiner le traitement en parallèle avec un certain volume, c'est-à-dire lorsque vous traitez de nombreux vecteurs en séquence.

Je l'ai corrigé. : O

C'était vraiment plutôt facile. Tout ce que je devais faire était de tourner

VectorData* m_Point;

dans

VectorData m_Point;

et mes problèmes ont disparu, sans besoin de malloc ou d'alignement.

Mais j'apprécie l'aide de tous! : D

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top