Technical Specification | ||||
Filesystem library(filesystem TS) | ||||
Library fundamentals(library fundamentals TS) | ||||
Library fundamentals 2(library fundamentals TS v2) | ||||
Library fundamentals 3(library fundamentals TS v3) | ||||
Extensions for parallelism(parallelism TS) | ||||
Extensions for parallelism 2(parallelism TS v2) | ||||
Extensions for concurrency(concurrency TS) | ||||
Extensions for concurrency 2(concurrency TS v2) | ||||
Concepts(concepts TS) | ||||
Ranges(ranges TS) | ||||
Reflection(reflection TS) | ||||
Mathematical special functions(special functions TR) | ||||
Experimental Non-TS | ||||
Pattern Matching | ||||
Linear Algebra | ||||
std::execution | ||||
Contracts | ||||
2D Graphics |
Parallel exceptions | ||||
Additional execution policies | ||||
Algorithms | ||||
Task blocks | ||||
Data-parallel vectors |
![]() | Merged into ISO C++ The functionality described on this page was merged into the mainline ISO C++ standard as of 11/2024; seethe 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 typesimd<T> behaves analogue to objects of typeT
. But whileT
stores and manipulates one value,simd<T>
stores and manipulates multiple values (calledwidth but identified assize for consistency with the rest of the standard library; cf.simd_size).
Every operator and operation onsimd<T>
actselement-wise (except forhorizontal 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 typessimd<T>
andnative_simd<T> is determined by the implementation at compile-time. In contrast, the width of the typefixed_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 usesnative_simd andrebind_simd:
#include <experimental/simd>namespace stdx= std::experimental; using floatv= stdx::native_simd<float>;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 thesplit andconcat functions.
Defined in header <experimental/simd> |
Contents |
(parallelism TS v2) | data-parallel vector type (class template)[edit] |
(parallelism TS v2) | data-parallel type with the element type bool (class template)[edit] |
Defined in namespace std::experimental::simd_abi | |
(parallelism TS v2) | tag type for storing a single element (typedef)[edit] |
(parallelism TS v2) | tag type for storing specified number of elements (alias template)[edit] |
(parallelism TS v2) | tag type that ensures ABI compatibility (alias template)[edit] |
(parallelism TS v2) | tag type that is most efficient (alias template)[edit] |
(parallelism TS v2) | the maximum number of elements guaranteed to be supported by fixed (constant)[edit] |
(parallelism TS v2) | obtains an ABI type for given element type and number of elements (class template)[edit] |
(parallelism TS v2) | flag indicating alignment of the load/store address to element alignment (class)[edit] |
(parallelism TS v2) | flag indicating alignment of the load/store address to vector alignment (class)[edit] |
(parallelism TS v2) | flag indicating alignment of the load/store address to the specified alignment (class template)[edit] |
(parallelism TS v2) | selected elements with non-mutating operations (class template) |
(parallelism TS v2) | selected elements with mutating operations (class template) |
(parallelism TS v2) | produces const_where_expression and where_expression (function template) |
(parallelism TS v2) | element-wise static_cast (function template) |
(parallelism TS v2) | element-wise ABI cast (function template) |
(parallelism TS v2) | splits single simd object to multiple ones (function template) |
(parallelism TS v2) | concatenates multiple simd objects to a single one (function template) |
(parallelism TS v2) | element-wise min operation (function template) |
(parallelism TS v2) | element-wise max operation (function template) |
(parallelism TS v2) | element-wise minmax operation (function template) |
(parallelism TS v2) | element-wise clamp operation (function template) |
(parallelism TS v2) | reduces the vector to a single element (function template) |
(parallelism TS v2) | reductions ofsimd_mask tobool (function template)[edit] |
(parallelism TS v2) | reduction ofsimd_mask to the number oftrue values (function template)[edit] |
(parallelism TS v2) | reductions ofsimd_mask to the index of the first or lasttrue value (function template)[edit] |
(parallelism TS v2) | checks if a type is asimd orsimd_mask type (class template)[edit] |
(parallelism TS v2) | checks if a type is an ABI tag type (class template)[edit] |
(parallelism TS v2) | checks if a type is a simd flag type (class template)[edit] |
(parallelism TS v2) | obtains the number of elements of a given element type and ABI tag (class template)[edit] |
(parallelism TS v2) | obtains an appropriate alignment forvector_aligned (class template)[edit] |
(parallelism TS v2) | change element type or the number of elements ofsimd orsimd_mask (class template)[edit] |
All functions in<cmath>, except for the special math functions, are overloaded forsimd
.
#include <experimental/simd>#include <iostream>#include <string_view>namespace stdx= std::experimental; void println(std::string_view name,autoconst& a){std::cout<< name<<": ";for(std::size_t i{}; i!=std::size(a);++i)std::cout<< a[i]<<' ';std::cout<<'\n';} template<class A>stdx::simd<int, A> my_abs(stdx::simd<int, A> x){ where(x<0, x)=-x;return x;} int main(){const stdx::native_simd<int> a=1; println("a", a); const stdx::native_simd<int> b([](int i){return i-2;}); println("b", b); constauto c= a+ b; println("c", c); constauto d= my_abs(c); println("d", d); constauto e= d* d; println("e", e); constauto inner_product= stdx::reduce(e);std::cout<<"inner product: "<< inner_product<<'\n'; const stdx::fixed_size_simd<longdouble,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: 6x: 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
numeric arrays, array masks and array slices (class template)[edit] |
1. | The implementation of ISO/IEC TS 19570:2018 Section 9 "Data-Parallel Types" — github.com |
2. | TS implementation reach forGCC/libstdc++ (std::experimental::simd is shipping with GCC-11) — gcc.gnu.org |