No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
benchmarks
detail
testsuite
vec
.gitignore
CMakeLists.txt
COPYING
README
simd_binary_arithmetic.hpp
simd_horizontal_functions.hpp
simd_math.hpp
simd_memory.hpp
simd_mix.hpp
simd_pan.hpp
simd_peakmeter.hpp
simd_ternary_arithmetic.hpp
simd_unary_arithmetic.hpp
simd_unit_conversion.hpp
simd_unroll_constraints.hpp
simd_utils.hpp
softclip.hpp
vec.hpp

README

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.