gpt4 book ai didi

c++ - AVX2:AVX 寄存器中 8 位元素上的 BitScanReverse 或 CountLeadingZeros

转载 作者:行者123 更新时间:2023-12-04 12:04:35 26 4
gpt4 key购买 nike

我想提取具有 8 位元素的 256 位 AVX 寄存器中最高设置位的索引。我找不到 bsr也不是 clz为此实现。
对于 clz对于 32 位元素,有一个带有浮点转换的 bithack,但这对于 8 位来说可能是不可能的。
目前,我正在研究一个解决方案,在那里我逐个检查位,稍后我会添加,但我想知道是否有更快的方法来做到这一点。

最佳答案

这是一个 vpshufb基于的解决方案。这个想法是将输入分成两半,对两者进行查找并合并结果:

__m256i clz_epu8(__m256i values)
{
// extract upper nibble:
__m256i hi = _mm256_and_si256(_mm256_srli_epi16(values, 4), _mm256_set1_epi8(0xf));
// this sets the highest bit for values >= 0x10 and otherwise keeps the lower nibble unmodified:
__m256i lo = _mm256_adds_epu8(values, _mm256_set1_epi8(0x70));

// lookup tables for count-leading-zeros (replace this by _mm256_setr_epi8, if this does not get optimized away)
// ideally, this should compile to vbroadcastf128 ...
const __m256i lookup_hi = _mm256_broadcastsi128_si256(_mm_setr_epi8(0, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0));
const __m256i lookup_lo = _mm256_broadcastsi128_si256(_mm_setr_epi8(8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4));

// look up each half
__m256i clz_hi = _mm256_shuffle_epi8(lookup_hi, hi);
__m256i clz_lo = _mm256_shuffle_epi8(lookup_lo, lo);

// combine results (addition or xor would work as well)
return _mm256_or_si256(clz_hi, clz_lo);
}
带有粗略测试的godbolt-link: https://godbolt.org/z/MYq74Wxdh

关于c++ - AVX2:AVX 寄存器中 8 位元素上的 BitScanReverse 或 CountLeadingZeros,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68985039/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com