SIMD library - cppreference.com (original) (raw)
![]() |
Merged into ISO C++ The functionality described on this page was merged into the mainline ISO C++ standard as of 11/2024; see the data-parallel types (SIMD) (since C++26) |
|---|
The SIMD library provides portable types for explicitly stating data-parallelism and structuring data for more efficient SIMD access.
An object of type simd behaves analogue to objects of type T. But while T stores and manipulates one value, simd<T> stores and manipulates multiple values (called width but identified as size for consistency with the rest of the standard library; cf. simd_size).
Every operator and operation on simd<T> acts element-wise (except for horizontal operations, which are clearly marked as such). This simple rule expresses data-parallelism and will be used by the compiler to generate SIMD instructions and/or independent execution streams.
The width of the types simd<T> and native_simd is determined by the implementation at compile-time. In contrast, the width of the type fixed_size_simd<T, N> is fixed by the developer to a certain size.
A recommended pattern for using a mix of different SIMD types with high efficiency uses native_simd and rebind_simd:
#include <experimental/simd> namespace stdx = std::experimental; using floatv = stdx::native_simd; using doublev = stdx::rebind_simd_t<double, floatv>; using intv = stdx::rebind_simd_t<int, floatv>;
This ensures that the set of types all have the same width and thus can be interconverted. A conversion with mismatching width is not defined because it would either drop values or have to invent values. For resizing operations, the SIMD library provides the split and concat functions.
Contents
- 1 Main classes
- 2 ABI tags
- 3 Alignment tags
- 4 Where expression
- 5 Casts
- 6 Algorithms
- 7 Reduction
- 8 Mask reduction
- 9 Traits
- 10 Math functions
- 11 Example
- 12 See also
- 13 External links
[edit] Main classes
| | data-parallel vector type (class template) [edit] | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | | data-parallel type with the element type bool (class template) [edit] |
[edit] ABI tags
| Defined in namespace std::experimental::simd_abi | |
|---|---|
| scalar(parallelism TS v2) | tag type for storing a single element (typedef) [edit] |
| fixed_size(parallelism TS v2) | tag type for storing specified number of elements(alias template)[edit] |
| compatible(parallelism TS v2) | tag type that ensures ABI compatibility(alias template)[edit] |
| native(parallelism TS v2) | tag type that is most efficient(alias template)[edit] |
| max_fixed_size(parallelism TS v2) | the maximum number of elements guaranteed to be supported by fixed (constant) [edit] |
| deducededuce_t(parallelism TS v2) | obtains an ABI type for given element type and number of elements (class template) [edit] |
[edit] Alignment tags
[edit] Where expression
| | selected elements with non-mutating operations (class template) | | ------------------------------------------------------------------------------ | | | selected elements with mutating operations (class template) | | | produces const_where_expression and where_expression (function template) |
[edit] Casts
[edit] Algorithms
| | element-wise min operation (function template) | | ---------------------------------------------------- | | | element-wise max operation (function template) | | | element-wise minmax operation (function template) | | | element-wise clamp operation (function template) |
[edit] Reduction
| | reduces the vector to a single element (function template) | | ------------------------------------------------------------- |
[edit] Mask reduction
[edit] Traits
| is_simdis_simd_mask(parallelism TS v2) | checks if a type is a simd or simd_mask type (class template) [edit] |
|---|---|
| is_abi_tag(parallelism TS v2) | checks if a type is an ABI tag type (class template) [edit] |
| is_simd_flag_type(parallelism TS v2) | checks if a type is a simd flag type (class template) [edit] |
| simd_size(parallelism TS v2) | obtains the number of elements of a given element type and ABI tag (class template) [edit] |
| memory_alignment(parallelism TS v2) | obtains an appropriate alignment for vector_aligned (class template) [edit] |
| rebind_simdresize_simd(parallelism TS v2) | change element type or the number of elements of simd or simd_mask (class template) [edit] |
[edit] Math functions
All functions in , except for the special math functions, are overloaded for simd.
[edit] Example
#include <experimental/simd> #include #include namespace stdx = std::experimental; void println(std::string_view name, auto const& a) { std::cout << name << ": "; for (std::size_t i{}; i != std::size(a); ++i) std::cout << a[i] << ' '; std::cout << '\n'; } template stdx::simd<int, A> my_abs(stdx::simd<int, A> x) { where(x < 0, x) = -x; return x; } int main() { const stdx::native_simd a = 1; println("a", a); const stdx::native_simd b([](int i) { return i - 2; }); println("b", b); const auto c = a + b; println("c", c); const auto d = my_abs(c); println("d", d); const auto e = d * d; println("e", e); const auto inner_product = stdx::reduce(e); std::cout << "inner product: " << inner_product << '\n'; const stdx::fixed_size_simd<long double, 16> x([](int i) { return i; }); println("x", x); println("cos²(x) + sin²(x)", stdx::pow(stdx::cos(x), 2) + stdx::pow(stdx::sin(x), 2)); }
Output:
a: 1 1 1 1 b: -2 -1 0 1 c: -1 0 1 2 d: 1 0 1 2 e: 1 0 1 4 inner product: 6 x: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cos²(x) + sin²(x): 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[edit] See also
| | numeric arrays, array masks and array slices (class template) [edit] | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
