Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Data-parallel types (SIMD)(since C++26)

      From cppreference.com
      <cpp‎ |numeric
       
       
       
       

      The library provides data-parallel types and operations on these types: portable types for explicitly stating data-parallelism and structuring data through data-parallel execution resources where available, such asSIMD registers and instructions or execution units that are driven by a common instruction decoder.

      The set ofvectorizable types comprises:

      Adata-parallel type consists of one or more elements of an underlying vectorizable type, called theelement type . The number of elements, called thewidth , is constant for each data-parallel type.

      The data-parallel type refers to all enabled specializations of the class templatesbasic_simd andbasic_simd_mask.

      Adata-parallel object of data-parallel type behaves analogously to objects of typeT. But whileT stores and manipulates a single value, the data-parallel type with the element typeT stores and manipulates multiple values.

      Every operation on a data-parallel object actselement-wise (except for horizontal operations, such as reductions, which are clearly marked as such) applying to each element of the object or to corresponding elements of two objects. Each such application is unsequenced with respect to the others. This simple rule expresses data-parallelism and will be used by the compiler to generate SIMD instructions and/or independent execution streams.

      All operations (except non-constexpr math function overloads) on data-parallel objects areconstexpr: it is possible to create and use data-parallel objects in the evaluation of a constant expression.

      Alias templatessimd andsimd_mask are defined to allow users to specify the width to a certain size. The default width is determined by the implementation at compile-time.

      Defined in header<simd>
      Defined in namespacestd::datapar

      Contents

      [edit]Main classes

      data-parallel vector type
      (class template)[edit]
      convenience alias template forbasic_simd that can specify its width
      (alias template)[edit]
      data-parallel type with the element typebool
      (class template)[edit]
      convenience alias template forbasic_simd_mask that can specify its width
      (alias template)[edit]

      [edit]Load and store flags

      load and store flags for data-parallel types
      (class template)[edit]
      default flag used on load and store operations
      (constant)[edit]
      flag enabling conversions that are not value-preserving on load and store operations
      (constant)[edit]
      flag indicating alignment of the load-store address to some specified storage to the value ofdatapar::alignment
      (constant)[edit]
      flag indicating alignment of the load-store address to some specified storage to the specified alignment
      (variable template)[edit]

      [edit]Load and store operations

      loads elements from a contiguous range tobasic_simd
      (function template)[edit]
      stores elements frombasic_simd to a contiguous range
      (function template)[edit]

      [edit]Casts

      splits single data-parallel object to multiple ones
      (function template)[edit]
      concatenates multiple data-parallel objects into a single one
      (function template)[edit]

      [edit]Algorithms

      element-wise min/max operations forbasic_simd
      (function template)[edit]
      element-wise clamp operation forbasic_simd
      (function template)[edit]
      element-wise selection using conditional operator
      (function template)[edit]

      [edit]Reductions

      reduces all values inbasic_simd over a specified binary operation to a single value
      (function template)[edit]
      reductions ofbasic_simd_mask tobool
      (function template)[edit]
      reduction ofbasic_simd_mask to number oftrue values
      (function template)[edit]
      reductions ofbasic_simd_mask to the index of first or lasttrue value
      (function template)[edit]

      [edit]Traits

      obtains an appropriate alignment fordatapar::flag_aligned
      (class template)[edit]
      changes element type of the data-parallel type
      (class template)[edit]
      changes the width of the data-parallel type
      (class template)[edit]

      [edit]Math functions

      All functions in<cmath> and<complex> are overloaded forbasic_simd.

      This section is incomplete
      Reason: description

      [edit]Bit manipulation functions

      All bit manipulation functions in<bit> are overloaded forbasic_simd.

      This section is incomplete
      Reason: description

      [edit]Implementation details

      [edit]ABI tags

      The data-parallel typesbasic_simd andbasic_simd_mask are associated withABI tags . These tags are types that specify the size and binary representation of data-parallel objects. The design intends the size and binary representation to vary based on target architecture and compiler flags. The ABI tag, together with the element type, determines the width.

      The ABI tag remains independent of machine instruction set selection. The chosen machine instruction set limits the usable ABI tag types. The ABI tags enable users to safely pass objects of data-parallel type across translation unit boundaries.

      This section is incomplete

      [edit]Exposition-only entities

      This section is incomplete
      Reason: needs update
      using/*simd-size-type*/=/* see description */;
      (1)(exposition only*)
      template<std::size_t Bytes>
      using/*integer-from*/=/* see description */;
      (2)(exposition only*)
      template<class T,class Abi>
      constexpr/*simd-size-type*//*simd-size-v*/=/* see description */;
      (3)(exposition only*)
      template<class T>
      constexprstd::size_t/*mask-element-size*/=/* see description */;
      (4)(exposition only*)
      template<class T>
      concept/*constexpr-wrapper-like*/=/* see description */;
      (5)(exposition only*)
      template<class T>
      using/*deduced-simd-t*/=/* see description */;
      (6)(exposition only*)
      template<class V,class T>
      using/*make-compatible-simd-t*/=/* see description */;
      (7)(exposition only*)
      1)/*simd-size-type*/ is an alias for for a signed integer type. The implementation is free to choose any signed integer type.
      2)/*integer-from*/<Bytes> is an alias for a signed integer typeT such thatsizeof(T) equalsBytes.
      3)/*simd-size-v*/<T, Abi> denotes the width of the enabled specializationbasic_simd<T, Abi>, or0 otherwise.
      4) IfT denotesstd::datapar::basic_simd_mask<Bytes, Abi>,/*mask-element-size*/<T> equalsBytes.
      5) The concept/*constexpr-wrapper-like*/ is defined as:
      template<class T>concept/*constexpr-wrapper-like*/=std::convertible_to<T, decltype(T::value)>&&std::equality_comparable_with<T, decltype(T::value)>&&std::bool_constant<T()== T::value>::value&&std::bool_constant<static_cast<decltype(T::value)>(T())== T::value>::value;
      6) Letx be an lvalue of typeconst T./*deduced-simd-t*/<T> is an alias equivalent to:
      • decltype(x+ x), if the type ofx+ x is an enabled specialization ofbasic_simd; otherwise
      • void.
      7) Letx be an lvalue of typeconst T./*make-compatible-simd-t*/<V, T> is an alias equivalent to:
      • /*deduced-simd-t*/<T>, if that type is notvoid, otherwise
      • std::datapar::simd<decltype(x+ x), V​::​size()>.
      Math functions requirements
      template<class V>
      concept/*simd-floating-point*/=/* see description */;
      (8)(exposition only*)
      template<class...Ts>
      concept/*math-floating-point*/=/* see description */;
      (9)(exposition only*)
      template<class...Ts>

        requires/*math-floating-point*/<Ts...>

      using/*math-common-simd-t*/=/* see description */;
      (10)(exposition only*)
      template<class BinaryOp,class T>
      concept/*reduction-binary-operation*/=/* see description */;
      (11)(exposition only*)
      8) The concept/*simd-floating-point*/ is defined as:
      template<class V>concept/*simd-floating-point*/=std::same_as<V,                 std::datapar::basic_simd<typename V::value_type,typename V::abi_type>>&&std::is_default_constructible_v<V>&&std::floating_point<typename V::value_type>;
      9) The concept/*math-floating-point*/ is defined as:
      template<class...Ts>concept/*math-floating-point*/=(/*simd-floating-point*/</*deduced-simd-t*/<Ts>>|| ...);
      10) LetT0 denoteTs...[0],T1 denoteTs...[1], andTRest denote a pack such thatT0, T1, TRest... is equivalent toTs.... Then,/*math-common-simd-t*/<Ts...> is an alias equivalent to:
      • /*deduced-simd-t*/<T0>, ifsizeof...(Ts)==1 istrue
      • otherwise,std::common_type_t</*deduced-simd-t*/<T0>,/*deduced-simd-t*/<T1>>, ifsizeof...(Ts)==2 istrue and/*math-floating-point*/<T0>&&/*math-floating-point*/<T1> istrue,
      • otherwise,std::common_type_t</*deduced-simd-t*/<T0>, T1> ifsizeof...(Ts)==2 istrue and/*math-floating-point*/<T0> istrue,
      • otherwise,std::common_type_t<T0,/*deduced-simd-t*/<T1>> ifsizeof...(Ts)==2 istrue,
      • otherwise,std::common_type_t</*math-common-simd-t*/<T0, T1>, TRest...>, if/*math-common-simd-t*/<T0, T1> is a valid type,
      • otherwise,std::common_type_t</*math-common-simd-t*/<TRest...>, T0, T1>.
      11) The concept/*reduction-binary-operation*/ is defined as:
      template<class BinaryOp,class T>concept/*reduction-binary-operation*/=    requires(const BinaryOp binary_op,const std::datapar::simd<T,1> v){{ binary_op(v, v)}->std::same_as<std::datapar::simd<T,1>>;};

      /*reduction-binary-operation*/<BinaryOp, T> is modeled only if:

      • BinaryOp is a binary element-wise operation that is commutative, and
      • An object of typeBinaryOp is invocable with two arguments of typestd::datapar::basic_simd<T, Abi> for unspecified ABI tagAbi that returns astd::datapar::basic_simd<T, Abi>.
      SIMD ABI tags
      template<class T>
      using/*native-abi*/=/* see description */;
      (12)(exposition only*)
      template<class T,/*simd-size-type*/ N>
      using/*deduce-abi-t*/=/* see description */;
      (13)(exposition only*)
      12)/*native-abi*/<T> is an implementation-defined alias for an ABI tag. This is the primary ABI tag to use for efficient explicit vectorization. As a result,basic_simd<T,/*native-abi*/<T>> is an enabled specialization.
      13)/*deduce-abi-t*/<T, N> is an alias that names an ABI tag type such that:
      • /*simd-size-v*/<T,/*deduce-abi-t*/<T, N>> equalsN,
      • std::datapar::basic_simd<T,/*deduce-abi-t*/<T, N>> is an enabled specialization, and
      • std::datapar::basic_simd_mask<sizeof(T),/*deduce-abi-t*/</*integer-from*/<sizeof(T)>, N>> is an enabled specialization.
      It is defined only ifT is a vectorizable type, andN>0&& N<= M istrue, whereM is an implementation-defined maximum that is at least64 and can differ depending onT.
      Load and store flags
      struct/*convert-flag*/;
      (14)(exposition only*)
      struct/*aligned-flag*/;
      (15)(exposition only*)
      template<std::size_t N>
      struct/*overaligned-flag*/;
      (16)(exposition only*)
      14-16) These tag types are used as a template argument ofstd::datapar::flags. Seeload and store flags for their corresponding uses.

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_lib_simd202411L(C++26)Data-parallel types and operations
      __cpp_lib_simd_complex202502L(C++26)Support of interleaved complex values instd::datapar::simd

      [edit]Example

      Run this code
      #include <iostream>#include <simd>#include <string_view> void println(std::string_view name,autoconst& a){std::cout<< name<<": ";for(std::size_t i{}; i!= a.size();++i)std::cout<< a[i]<<' ';std::cout<<'\n';} template<class A>constexpr std::datapar::basic_simd<int, A> my_abs(std::datapar::basic_simd<int, A> x){return std::datapar::select(x<0,-x, x);} int main(){constexpr std::datapar::simd<int> a=1;    println("a", a); constexpr std::datapar::simd<int> b([](int i){return i-2;});    println("b", b); constexprauto c= a+ b;    println("c", c); constexprauto d= my_abs(c);    println("d", d); constexprauto e= d* d;    println("e", e); constexprauto inner_product= std::datapar::reduce(e);std::cout<<"inner product: "<< inner_product<<'\n'; constexpr std::datapar::simd<double,16> x([](int i){return i;});    println("x", x);// overloaded math functions are defined in <simd>    println("cos²(x) + sin²(x)",std::pow(std::cos(x),2)+std::pow(std::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

      [edit]See also

      numeric arrays, array masks and array slices
      (class template)[edit]

      [edit]External links

      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
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/simd&oldid=182913"

      [8]ページ先頭

      ©2009-2025 Movatter.jp