Compute whether packed values may overflow SIMD register. Due to packing misalignment, we may not be able to fit in a SIMD register as many packed values as unpacked values. This happens because of the packing bit alignment creates spare bits we are forced to read when reading whole bytes. This is mostly known to be the case with 63 bits values in a 128 bit SIMD register. @see KernelShape @see P
| 224 | /// @see KernelShape |
| 225 | /// @see PackedMaxSpreadBytes |
| 226 | ARROW_FORCE_INLINE constexpr bool PackedIsOversizedForSimd(int simd_bit_size, |
| 227 | int unpacked_bit_size, |
| 228 | int packed_bit_size) { |
| 229 | const int unpacked_per_simd = simd_bit_size / unpacked_bit_size; |
| 230 | |
| 231 | const auto packed_per_read_for_offset = [&](int bit_offset) -> int { |
| 232 | return (simd_bit_size - bit_offset) / packed_bit_size; |
| 233 | }; |
| 234 | |
| 235 | int packed_start_bit = 0; |
| 236 | // Try all possible bit offsets for this packed size |
| 237 | do { |
| 238 | int packed_per_read = packed_per_read_for_offset(packed_start_bit % 8); |
| 239 | if (packed_per_read < unpacked_per_simd) { |
| 240 | // A single SIMD batch isn't enough to unpack from this bit offset, |
| 241 | // so the "medium" model cannot work. |
| 242 | return true; |
| 243 | } |
| 244 | packed_start_bit += unpacked_per_simd * packed_bit_size; |
| 245 | } while (packed_start_bit % 8 != 0); |
| 246 | |
| 247 | return false; |
| 248 | } |
| 249 | |
| 250 | /// Different sizes of a given kernel. |
| 251 | /// |