Created
January 17, 2018 22:55
-
-
Save rolandschulz/7c75ab97adae3ff60972c795b2a4c0c3 to your computer and use it in GitHub Desktop.
Proof of concept of multi-versioned SIMD type and dispatch function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <immintrin.h> | |
#ifdef __ICC //ICC>=16 | |
#define USE_TARGET_ATTR 0 | |
#else //Clang (>=3.8) or GCC | |
#define USE_TARGET_ATTR 1 | |
#endif | |
#if USE_TARGET_ATTR | |
#define TARGET_AVX __attribute__ ((target ("avx"))) | |
#else | |
#define TARGET_AVX | |
#endif | |
struct SimdTagSSE {}; | |
struct SimdTagAVX {}; | |
template<class T> | |
class SimdFloat; | |
template<> | |
class SimdFloat<SimdTagSSE> | |
{ | |
public: | |
SimdFloat(float x) : storage(_mm_set1_ps(x)) {}; | |
__m128 storage; | |
}; | |
template<> | |
class SimdFloat<SimdTagAVX> | |
{ | |
public: | |
//TARGET_AVX SimdFloat(const SimdFloat& o) = default; | |
TARGET_AVX SimdFloat(float x) : storage(_mm256_set1_ps(x)) {}; | |
__m256 storage; | |
}; | |
template<class T> | |
static inline T foo() | |
{ | |
return 1; | |
} | |
//static inline void store(float *m, const SimdFloat<SimdTagSSE>& x) | |
static inline void store(float *m, SimdFloat<SimdTagSSE> x) | |
{ | |
_mm_store_ps(m, x.storage); | |
} | |
//TARGET_AVX static inline void store(float *m, const SimdFloat<SimdTagAVX>& x) | |
TARGET_AVX static inline void store(float *m, SimdFloat<SimdTagAVX> x) //requires GCC>=7.3 and even then produces inefficinet code, ICC and clang is fine | |
{ | |
_mm256_store_ps(m, x.storage); | |
} | |
template<class T> | |
struct do_func { | |
void operator()(float *f) | |
{ | |
T x = foo<T>(); | |
store(f, x); | |
} | |
}; | |
template<template<typename> class F, class...Args> | |
static inline void dispatch(Args...args) | |
{ | |
if (__builtin_cpu_supports("avx")) | |
[&]() TARGET_AVX | |
{F<SimdFloat<SimdTagAVX>>()(args...);}(); | |
else | |
F<SimdFloat<SimdTagSSE>>()(args...); | |
} | |
int main() | |
{ | |
float f[16]; | |
dispatch<do_func>(f); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment