c++ - 将 32 0/1 值打包到单个 32 位变量的位中的最快方法是什么?

标签 c++ c performance bit-manipulation

我正在 x86 或 x86_64 机器上工作。我有一个数组 unsigned int a[32],其所有元素的值为 0 或 1。我想设置单个变量 unsigned int b 以便 (b >> i) & 1 == a[i] 将适用于 a 的所有 32 个元素。我在 Linux 上使用 GCC(我想应该无关紧要)。

在 C 中执行此操作的最快方法是什么?

最佳答案

最近的 x86 处理器上最快的方法可能是使用 MOVMSKB 系列指令,它提取 SIMD 字的 MSB 并将它们打包到一个普通的整数寄存器中。

我担心 SIMD 内在函数不是我真正喜欢的东西,但如果你有配备 AVX2 的处理器,那么按照这些思路应该可以工作:

uint32_t bitpack(const bool array[32]) {
    __mm256i tmp = _mm256_loadu_si256((const __mm256i *) array);
    tmp = _mm256_cmpgt_epi8(tmp, _mm256_setzero_si256());
    return _mm256_movemask_epi8(tmp);
}

假设 sizeof(bool) = 1。对于较旧的 SSE2 系统,您将不得不将一对 128 位操作串在一起。在 32 字节边界上对齐数组,应该可以节省另一个周期左右。

关于c++ - 将 32 0/1 值打包到单个 32 位变量的位中的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26200961/

相关文章:

c - 使用#define 为结构成员起别名

sql - 逻辑读取是如何计算的?

mysql - 列出与 WordPress 中当前帖子具有相同标签的帖子

c++ - 在未排序的对数组中查找 K UNIQUE 最大元素

c++ - CreateSymbolicLink 相当于 “mklink/J” ?

c++ - 使用 EVT_NAVIGATION_KEY 处理事件不起作用

c++ - 为什么无法从 "read"获取数据到 uint8_t 数组?

c - 从 Nautilus 获取文件大小属性

c - 将变量的内容分配给指针在 C 和 proC 中不起作用

c++ - 使用 this-> 访问成员是否有任何开销?