gorill
gorill

Reputation: 1673

Switch SSE intrinsics using templates

I use template specialization way to switch float/double SSE-intrinsics:

template<typename Precision>
struct simd
{
    typedef Precision simd_vector;
};

template<>
struct simd<float>
{
    typedef __m128 simd_vector;
};

template<>
struct simd<double>
{
    typedef __m128d simd_vector;
};

int main()
{
    simd<float>::simd_vector float_vector;//__m128
    simd<double>::simd_vector double_vector;//__m128d
}

It works well, but I can't understand how to use SSE-intrinsics functions in the same way? Assume that we want switch add-operation: _mm_add_ps intrinsic - for float, and _mm_add_pd for double. How can I use template specialisation trick for it?

Upvotes: 3

Views: 724

Answers (2)

pippin1289
pippin1289

Reputation: 4939

What you can do is specialize each class with appropriate functions which call their appropriate functions.

template<>
struct simd<float>
{
    typedef __m128 simd_vector;
    simd_vector v;

    simd operator+(const simd& _s){
       //call my simd function for floats to operator on v
    }
};

template<>
struct simd<double>
{
    typedef __m128d simd_vector;
    simd_vector v;

    simd operator+(const simd& _s){
        //call my simd function for doubles to operate on v
    }
};

And how to use this would be:

simd<float> sf1, sf2;
simd<float> sf3 = sf1+sf2;
//get vector throw sd3.v;
simd<double> sd1, sd2;
simd<double> sd3 = sd1 + sd2;
//get vector through sd3.v;

Of course you need to appropriately initialize sf1, sf2, sd1, sd2.

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129474

Since you probably need to produce a line for every single operation you can imagine, you may just as well implement proper operators:

template<>
struct simd<double>
{
    typedef __m128d simd_vector;
};

simd<float>::simd_vector operator+(simd<float>::simd_vector a, simd<float>::simd_vector b)
{
    return _mm_add_ps(a, b);
}

etc.

Upvotes: 4

Related Questions