mask type for hwy_simd_type. This is a type which holds a set of masks stored in uint8_t, as the highway mask storing function provides. So this type is memory-backed, just like hwy_simd_type. Template arguments are the corresponding hwy_simd_type's tag type and it's lane count. highway is strict about which vectors and masks can interoperate, and only allows 'direct' interoperation if the types involved 'match' in size. Masks pertaining to vectors of differently-sized T aren't directly interoperable because they don't have the same lane count. One requires k masks of one type and k * 2 ^ i of the other. Here, we follow a different paradigm: The top-level objects we're dealing with have a fixed 'vsize', the number of lanes they hold. This should be a power of two. The paradigm is that objects with equal vsize should be interoperable, no matter what lane count the hardware vectors have which are used to implement their functionality. This makes user code simpler: users pick a vsize which they use for a body of code, all vector-like objects use the common vsize, and the implementation of the vector-like objects takes care of 'rolling out' the operations to hardware vectors. At times this produces what I call 'friction' - if the underlying hardware vectors and masks are not directly compatible, code is needed to interoperate them, and this code can at times be slow. So the recommendation for users is to avoid 'friction' by avoiding mixing differently-sized types, but with the given paradigm, this is a matter of performance tuning rather than imposing constraints on code structure. Some of the 'friction' might be mitigated by additional code using highway's up- and down-scaling routines, but for now the code rather uses 'goading' with small loops over the backing memory, relying on the compiler to handle this efficiently.
More...
#include <hwy_simd_type.h>
|
static constexpr std::size_t | L () |
|
template<typename D, std::size_t _vsize>
struct HWY_NAMESPACE::mchunk_t< D, _vsize >
mask type for hwy_simd_type. This is a type which holds a set of masks stored in uint8_t, as the highway mask storing function provides. So this type is memory-backed, just like hwy_simd_type. Template arguments are the corresponding hwy_simd_type's tag type and it's lane count. highway is strict about which vectors and masks can interoperate, and only allows 'direct' interoperation if the types involved 'match' in size. Masks pertaining to vectors of differently-sized T aren't directly interoperable because they don't have the same lane count. One requires k masks of one type and k * 2 ^ i of the other. Here, we follow a different paradigm: The top-level objects we're dealing with have a fixed 'vsize', the number of lanes they hold. This should be a power of two. The paradigm is that objects with equal vsize should be interoperable, no matter what lane count the hardware vectors have which are used to implement their functionality. This makes user code simpler: users pick a vsize which they use for a body of code, all vector-like objects use the common vsize, and the implementation of the vector-like objects takes care of 'rolling out' the operations to hardware vectors. At times this produces what I call 'friction' - if the underlying hardware vectors and masks are not directly compatible, code is needed to interoperate them, and this code can at times be slow. So the recommendation for users is to avoid 'friction' by avoiding mixing differently-sized types, but with the given paradigm, this is a matter of performance tuning rather than imposing constraints on code structure. Some of the 'friction' might be mitigated by additional code using highway's up- and down-scaling routines, but for now the code rather uses 'goading' with small loops over the backing memory, relying on the compiler to handle this efficiently.
Definition at line 151 of file hwy_simd_type.h.
template<typename D , std::size_t _vsize>
◆ value_type
template<typename D , std::size_t _vsize>
◆ vec_t
template<typename D , std::size_t _vsize>
◆ vmask_type
template<typename D , std::size_t _vsize>
◆ mchunk_t() [1/4]
template<typename D , std::size_t _vsize>
◆ mchunk_t() [2/4]
template<typename D , std::size_t _vsize>
◆ mchunk_t() [3/4]
template<typename D , std::size_t _vsize>
◆ mchunk_t() [4/4]
template<typename D , std::size_t _vsize>
template<typename D2 >
◆ all_of()
template<typename D , std::size_t _vsize>
◆ any_of()
template<typename D , std::size_t _vsize>
◆ data() [1/2]
template<typename D , std::size_t _vsize>
◆ data() [2/2]
template<typename D , std::size_t _vsize>
◆ L()
template<typename D , std::size_t _vsize>
◆ LoadFromBytes()
template<typename D , std::size_t _vsize>
◆ none_of()
template<typename D , std::size_t _vsize>
◆ operator=() [1/2]
template<typename D , std::size_t _vsize>
◆ operator=() [2/2]
template<typename D , std::size_t _vsize>
template<typename D2 >
◆ SaveToBytes()
template<typename D , std::size_t _vsize>
◆ take()
template<typename D , std::size_t _vsize>
◆ transfer()
template<typename D , std::size_t _vsize>
template<typename D1 , typename D2 >
◆ yield()
template<typename D , std::size_t _vsize>
◆ operator<<
template<typename D , std::size_t _vsize>
std::ostream & operator<< |
( |
std::ostream & |
osr, |
|
|
mchunk_t< D, _vsize > |
it |
|
) |
| |
|
friend |
◆ mask_bytes
template<typename D , std::size_t _vsize>
◆ vsize
template<typename D , std::size_t _vsize>
The documentation for this struct was generated from the following file: