【问题标题】:Difficulty in loading boolean array using AVX2 instruction使用 AVX2 指令加载布尔数组时遇到困难
【发布时间】:2021-10-08 09:51:50
【问题描述】:

目前我有两个布尔数组 X 和 Y,我想对它们进行按位或运算并将其存储回 X。我希望使用 SIMD 指令来执行此操作,但我发现我使用的加载指令是没有达到预期的效果。

#include <iostream>
#include <immintrin.h>

int main(){
    bool mask[256]={0};
    mask[130] = 1;
    bool block_bloom[256]={0};
    bool a[256] = {0};
    __m256i reg1 = _mm256_loadu_si256((__m256i*)(&mask[0]));
    __m256i reg2 = _mm256_loadu_si256((__m256i*)(&block_bloom[0]));
    reg2 = _mm256_or_si256(reg1, reg2);
    _mm256_storeu_si256((__m256i*) &a[0],reg2);
    std::cout<< a[130] << std::endl;
    std::cout<<mask[130];
}

正如我所料,这段代码应该给出输出 1 和 1,但输出是 0 和 1。我想知道我做错了什么以及如何解决它。非常感谢!

【问题讨论】:

    标签: c++ boolean bit avx2


    【解决方案1】:

    bool mask[256] 的大小是 256 字节而不是 256 位。数组元素的最小大小为 1 个字节。这意味着mask[130] 没有被_mm256_loadu_si256 加载。在加载到寄存器之前,您需要将布尔值打包成 256 位:

    #include <iostream>
    #include <immintrin.h>
    
    int main() {
        uint8_t mask[32] = { 0 };
        mask[16] = 1 << 5;
        uint8_t block_bloom[32] = { 0 };
        uint8_t a[32] = { 0 };
        __m256i reg1 = _mm256_loadu_si256((__m256i*)(&mask[0]));
        __m256i reg2 = _mm256_loadu_si256((__m256i*)(&block_bloom[0]));
        reg2 = _mm256_or_si256(reg1, reg2);
        _mm256_storeu_si256((__m256i*) & a[0], reg2);
        std::cout << ((a[16] >> 5) & 0x1) << std::endl;
        std::cout << ((mask[16] >> 5) & 0x1);
    }
    

    【讨论】:

    • 啊,非常感谢!我可以进一步问一下,我该如何打包我的布尔值?
    • 我知道我可以使用无符号整数来存储这个位数组,但有没有更好的方法?再次感谢!
    • @WenKaiyue 我加了一个例子
    • @文凯悦你可以使用std::bitset。但是,我不确定它是否保证可以轻松复制。事实上,我认为不是。虽然,它似乎与 libstdc++ 和 libc++ 一起使用。此外,在这两个实现中,它甚至为 AVX2 指令正确对齐:godbolt.org/z/McbWz6Kc7
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2019-04-09
    • 2011-07-25
    • 1970-01-01
    • 2021-12-16
    • 2019-03-03
    • 1970-01-01
    相关资源
    最近更新 更多