【问题标题】:AVX2 Gather Instruction Usage DetailsAVX2 收集指令使用详情
【发布时间】:2020-03-08 22:48:50
【问题描述】:

我正在尝试了解 AVX2 intel intrinsic 的收集功能。

根据官方文档Link,函数定义为,

__m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale)

Gather 32-bit integers from memory using 32-bit indices. 32-bit elements are loaded from addresses starting at base_addr and offset by each 32-bit element in vindex (each index is scaled by the factor in scale). Gathered elements are merged into dst. scale should be 1, 2, 4 or 8.

因此,根据我的理解,它返回一个 __m256i 向量,其中填充了数组中的 8 个整数,其基索引为 base_addr,来自填充在 vindex 中的索引 (8)。如果提到任何scale,那么它也会成倍增加。现在,为了测试理解我写了一段代码,

#include<stdio.h>
#include <immintrin.h>
int main()
{
    __m256i var, ind_intel;
    int * arr = (int *) aligned_alloc(sizeof(__m256i), sizeof(int) * 64);
    int * out = (int *) aligned_alloc(sizeof(__m256i), sizeof(int) * 8);
    int * ind = (int *) aligned_alloc(sizeof(__m256i), sizeof(int) * 8);
    int i;
    ind[0] = 0;ind[1] = 2;ind[2] = 4;ind[3] = 6;ind[4] = 8;ind[5] = 10;ind[6] = 12;ind[7] = 14;
    ind_intel = _mm256_load_si256((__m256i *)&ind[0]);
    for(i=0;i<64;i++)
        arr[i] = i;
    var = _mm256_i32gather_epi32(arr,ind_intel,1);
    _mm256_store_si256((__m256i *)&out[0], var);
    for(i=0;i<8;i++)
        printf("%d ",out[i]);
    return 0;
}

现在,__m256i 变量 ind_intel 获取索引为 0,2,..,14。主数组arr 加载有0,1,..,63。因此,gather 应该将数据加载为arr[0],arr[2],..,arr[14]。但它正在打印价值,

0 65536 1 131072 2 196608 3 262144

当然,我错过了一些大事。但是我找不到任何网站或文件清楚地提到收集的用法。他们每个人都重复了与官方文档相同的描述。任何人都可以解释代码中的问题并理解吗?

注意该代码仅用于测试目的。

【问题讨论】:

    标签: c++ c intrinsics avx avx2


    【解决方案1】:

    vindex 中的偏移量以字节为单位。因此,您从地址 {arr, arr+2, arr+4, ...} 收集 32 位整数值。要么将这些索引从 {0,2,4...} 更改为 {0,8,16,...},要么将比例因子更新为:

    var = _mm256_i32gather_epi32(arr,ind_intel, 4 ); // 1 -> 4
    

    这会打印出预期值。

    我更喜欢第二种选择,即更新比例因子。基本上它的目的是——允许vindex 中的索引具有相对于数据字节大小的逻辑偏移值,而不是字节偏移值。

    【讨论】:

    • 是的,选择比例因子允许您使用元素索引、字节偏移(包括可能未对齐),甚至(以0 为基数)32 位指针。或带有 qword-index 集合的 64 位指针。
    • @PritamPallab 不客气。如果您不需要更多信息,请接受答案,以便其他人知道它已解决。
    猜你喜欢
    • 2013-04-18
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多