Read Me
nova simd
nova simd provides a framework of simdfied vector functions, designed
mainly for computer music applications.
it currently supports the following instruction sets:
- sse/sse2 family
- ppc/altivec
- avx
- arm/neon
vec class:
the simd functionality is built around a templated vec class. it usually maps
to a simd vector. the vec class can be used to compose more specific algorithms,
hiding different implementations under a common API.
template <typename FloatType>
class vec
{
public:
typedef FloatType float_type;
static const int size; // number of samples per vector
static const int objects_per_cacheline; // typical number of objects per cacheline
/* constructors */
vec(void);
vec(double f);
vec(float f);
vec(vec const & rhs);
/* element access */
FloatType get (int index) const;
/* set vector */
void set (int index, FloatType arg);
void set_vec (FloatType value);
FloatType set_slope(FloatType start, FloatType slope);
FloatType set_exp(FloatType start, FloatType curve);
/* load and store */
void load(const WrappedType * src);
void load_first(const WrappedType * src);
void load_aligned(const WrappedType * data);
void store(WrappedType * dest) const;
void store_aligned(WrappedType * dest) const;
void store_aligned_stream(WrappedType * dest) const;
void clear(void);
vec_base operator+(vec_base const & rhs) const
vec_base operator-(vec_base const & rhs) const
vec_base operator*(vec_base const & rhs) const
vec_base operator/(vec_base const & rhs) const
vec_base & operator+=(vec_base const & rhs)
vec_base & operator-=(vec_base const & rhs)
vec_base & operator*=(vec_base const & rhs)
vec_base & operator/=(vec_base const & rhs)
vec_base operator<(vec_base const & rhs) const
vec_base operator<=(vec_base const & rhs) const
vec_base operator==(vec_base const & rhs) const
vec_base operator!=(vec_base const & rhs) const
vec_base operator>(vec_base const & rhs) const
vec_base operator>=(vec_base const & rhs) const
friend vec madd(vec const & arg1, vec const & arg2, vec const & arg3);
friend vec sin(vec const & arg);
friend vec cos(vec const & arg);
friend vec tan(vec const & arg);
friend vec asin(vec const & arg);
friend vec acos(vec const & arg);
friend vec atan(vec const & arg);
friend vec tanh(vec const & arg);
friend vec log(vec const & arg);
friend vec log2(vec const & arg);
friend vec log10(vec const & arg);
friend vec exp(vec const & arg);
friend vec pow(vec const & lhs, vec const & rhs);
friend vec abs(vec const & arg);
friend vec sign(vec const & arg);
friend vec square(vec const & arg);
friend vec cube(vec const & arg);
friend vec signed_sqrt(vec const & arg);
friend vec signed_pow(vec const & lhs, vec const & rhs);
friend vec min_(vec const & lhs, vec const & rhs);
friend vec max_(vec const & lhs, vec const & rhs);
friend vec round(vec const & arg);
friend vec ceil(vec const & arg);
friend vec floor(vec const & arg);
friend vec frac(vec const & arg);
friend vec trunc(vec const & arg);
};
vector functions:
this vec class has been used as building block for a number of vector functions,
which provides a traditional c++-style interface to perform a specific operation
on buffers.
(for details consult the simd_*.hpp files)
for an unary operation `foo', the following functions must be:
/* arbitrary number of iterations */
template <typename float_type>
inline void foo_vec(float_type * out, const float_type * in, unsigned int n);
/* number of iterations must be a multiple of
* unroll_constraints<float_type>::samples_per_loop
*/
template <typename float_type>
inline void foo_vec_simd(float_type * out, const float_type * in, unsigned int n);
/* number of iterations must be a multiple of
* unroll_constraints<float_type>::samples_per_loop
*/
template <int n,
typename FloatType
>
inline void foo_vec_simd(FloatType * out, const FloatType * in);
for binary and ternary operations, instances are provided for mixed
vector and scalar arguments. using the suffix _simd provides versions for compile-time
and run-time unrolled code:
template <typename float_type,
typename Arg1,
typename Arg2
>
inline void foo_vec(float_type * out, Arg1 arg1, Arg2 arg2, unsigned int n);
template <typename float_type,
typename Arg1,
typename Arg2
>
inline void foo_vec_simd(float_type * out, Arg1 arg1, Arg2 arg2, unsigned int n);
template <unsigned int n,
typename float_type,
typename Arg1,
typename Arg2
>
inline void foo_vec_simd(float_type * out, Arg1 arg1, Arg2 arg2);
for scalar arguments, an extension is provided to support ramping by
adding a slope to the scalar after each iteration. for binary functions,
c++ function overloading is used. compile-time unrolled versions of these
functions are also provided.
argument wrapper:
to support different kinds of arguments with a generic interface, nova-simd provides
argument wrappers. these can be generated with the following functions:
/* wrap a scalar argument */
template <typename FloatType>
/unspecified/ nova::wrap_arguments(FloatType f);
/* wrap a vector argument */
template <typename FloatType>
/unspecified/ nova::wrap_arguments(const FloatType * f);
/* wrap a ramp argument */
template <typename FloatType>
/unspecified/ nova::wrap_arguments(FloatType base, FloatType slope);
building and testing:
nova simd is a header-only library, so it cannot be compiled as
standalone libray. however some benchmark and test programs are
provided, using a cmake build system.