Reputation: 1673
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
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
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