Functions that in different way expose compressing selected elements together to beginning. This is at the core of remove_if, copy_if etc. Alternative search keywords: filter, remove, pack
Variables | |
| constexpr callable_compress_ | eve::compress = {} |
| A low level function to compress one simd value based on a mask. | |
| constexpr auto | eve::compress_copy = _::compress_callable<compress_copy_core> {} |
| A function that copies selected elements from source to destination, while compressing them to the left. | |
| constexpr auto | eve::compress_store = _::compress_callable_no_density<compress_store_core> {} |
| A function that stores selected elements from an eve::simd_value to an eve::simd_compatible_ptr, while compressing them to the beginning. | |
|
inlineconstexpr |
A low level function to compress one simd value based on a mask.
Defined in Header
Compression in simd is moving selected elements to the front of the simd_value. Unfortunately, not for all simd_value, not for all platforms that can be done efficiently. So the operation splits the input into chunks for which it's possible.
The function performs the following steps: 1) splits the simd_value and mask into chunks, that can be processed in one go. This depends on what instructions are available. 2) Each chunk, gets shuffled in a way that moves selected elements (mask == true) to the front. The tail of the resulting value is unspecified. [a, b, c, d], (false, true, false, true) -> [b, d, _, _] 3) For each chunk we also compute how many elements are selected. (in the example - 2). 4) Both shuffled chunk and a number are put in a kumi::tuple<simd_value, std::ptrdiff_t> TODO: there is a bug where sometimes it's an int and not std::ptrdiff_t. 5) Those chunks are combined together in another tuple.
List of people who's work was instrumental for building this:
Throughout the code of compress there are references to what was taken from where as well as explanations.
Parameters
Return value
|
inlineconstexpr |
A function that copies selected elements from source to destination, while compressing them to the left.
Defined in Header
If this function doesn't work for you, maybe you are looking for eve::compress_store or eve::compress. However this function is faster.
You can think about this function as std::copy_if but instead of a predicate, you pass in logical_simd_value. Similar to std::copy_if it returns you a pointer to where the output ended.
There are the following two modifiers:
Very often the mask is computed based on the values loaded from input. We would expect the optimizer to eliminate duplicated loads, but for some very complex pointer-like it might not be able to.
So we provide overloads where you can pass an already preloaded value. It should match loaded value from in, otherwise the behaviour is unspecified.
You can pass up to two eve::relative_conditional_expr ignore modifiers. 1st is the input side ignore:
|
inlineconstexpr |
A function that stores selected elements from an eve::simd_value to an eve::simd_compatible_ptr, while compressing them to the beginning.
Defined in Header
This function behaves like eve::compress_copy[dense] but as input it takes loaded register.
Parameters
Return value