NSIMD documentation
Index | Tutorial | FAQ | Contribute | API overview | API reference | Wrapped intrinsics | Modules

Overview

NSIMD scalar types

Their names follow the following pattern: Sxx where

Full list of scalar types:

NSIMD generic SIMD vector types

In NSIMD, we call a platform an architecture e.g. Intel, ARM, POWERPC. We call SIMD extension a set of low-level functions and types provided by hardware vendors to access SIMD units. Examples include SSE2, SSE42, AVX, ... When compiling the generic SIMD vector types represents a SIMD register of the target. Examples are a __m128 for Intel SSE, __m512 for Intel AVX-512 or svfloat32_t for Arm SVE.

Their names follow the following pattern:

Full list of SIMD vector types:

Base type C base API C advanced API C++ advanced API
f64 vf64 nsimd_pack_f64 nsimd::pack<f64>
f32 vf32 nsimd_pack_f32 nsimd::pack<f32>
f16 vf16 nsimd_pack_f16 nsimd::pack<f16>
i64 vi64 nsimd_pack_i64 nsimd::pack<i64>
i32 vi32 nsimd_pack_i32 nsimd::pack<i32>
i16 vi16 nsimd_pack_i16 nsimd::pack<i16>
i8 vi8 nsimd_pack_i8 nsimd::pack<i8>
u64 vu64 nsimd_pack_u64 nsimd::pack<u64>
u32 vu32 nsimd_pack_u32 nsimd::pack<u32>
u16 vu16 nsimd_pack_u16 nsimd::pack<u16>
u8 vu8 nsimd_pack_u8 nsimd::pack<u8>

C/C++ base APIs

These come automatically when you include nsimd/nsimd.h. You do not need to include a header file for having a function. Here is a list of supported platforms and their corresponding SIMD extensions.

Each simd extension has its own set of SIMD types and functions. Types follow the pattern: nsimd_SIMDEXT_vSCALAR where

There are also logical types associated to each SIMD vector type. These types are used, for example, to represent the result of a comparison of SIMD vectors. They are usually bit masks. Their name follow the pattern: nsimd_SIMDEXT_vlSCALAR where

Note 1: Platform cpu is a 128 bits SIMD emulation fallback when no SIMD extension has been specified or is supported on a given compilation target.

Note 2: as all SIMD extensions of all platforms are different there is no need to put the name of the platform in each identifier.

Function names follow the pattern: nsimd_SIMDEXT_FUNCNAME_SCALAR where

Generic identifier

In the base C API, genericity is achieved using macros.

In C++98 and C++03, type traits are available.

In C++11 and beyond, type traits are still available but typedefs are also provided.

The C++20 API does not bring different types for SIMD registers nor other way to access the other SIMD types. It only brings concepts instead of usual typenames. For more informations cf. concepts.md.

Note that all macro and functions available in plain C are still available in C++.

List of operators provided by the base APIs

In the documentation we use interchangeably the terms "function" and "operator". For each operator FUNCNAME a C function (also available in C++) named nsimd_SIMDEXT_FUNCNAME_SCALAR is available for each SCALAR type unless specified otherwise.

For each FUNCNAME, a C macro (also available in C++) named vFUNCNAME is available and takes as its last argument a SCALAR type.

For each FUNCNAME, a C macro (also available in C++) named vFUNCNAME_a is available and takes as its two last argument a SCALAR type and a SIMDEXT.

For each FUNCNAME, a C++ function in namespace nsimd named FUNCNAME is available. It takes as its last argument the SCALAR type and can optionnally take the SIMDEXT as its last last argument.

For example, for the addition of two SIMD vectors a and b here are the possibilities:

c = nsimd_add_avx_f32(a, b); // use AVX
c = nsimd::add(a, b, f32()); // use detected SIMDEXT
c = nsimd::add(a, b, f32(), avx()); // force AVX even if detected SIMDEXT is not AVX
c = vadd(a, b, f32); // use detected SIMDEXT
c = vadd_e(a, b, f32, avx); // force AVX even if detected SIMDEXT is not AVX

Here is a list of available FUNCNAME.

C advanced API (only available in C11)

The C advanced API takes advantage of the C11 _Generic keyword to provide function overloading. Unlike the base API described above there is no need to pass as arguments the base type of the SIMD extension. The informations are contained in the types provided by this API.

There are versions of the above type without SIMDEXT for which the targeted SIMD extension is automatically chosen.

Generic types are also available:

Finally, operators are follow the naming: nsimd_FUNCNAME e.g. nsimd_add, nsimd_sub.

C++ advanced API

The C++ advanced API is called advanced not because it requires C++11 or above but because it makes use of the particular implementation of ARM SVE by ARM in their compiler. We do not know if GCC (and possibly MSVC in the distant future) will use the same approach. Anyway the current implementation allows us to put SVE SIMD vectors inside some kind of structs that behave like standard structs. If you want to be sure to write portable code do not use this API. Two new types are available.

Use N > 1 when declaring packs to have an unroll of N. This is particularily useful on ARM.

Functions that takes packs do not take any other argument unless specified otherwise e.g. the load family of funtions. It is impossible to determine the kind of pack (unroll and SIMDEXT) from the type of a pointer. Therefore in this case, the last argument must be a pack and this same type will then return. Also some functions are available as C++ operators. They follow the naming: nsimd::FUNCNAME.