You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在启用AVX2的VCL中实现任意索引的Gather操作?

使用VCL实现动态索引的Gather向量化

问题背景

需要向量化处理一段随机索引的代码,对vSource中由vInd指定索引的元素执行操作,原始串行代码如下:

vector<int> vSource;
vector<int> vInd;
for (auto i = 0; i < vSource.size();i++) {
    vSource[ vInd[i] ]; // 执行具体操作
}

其中vInd包含完全随机的索引,无法通过洗牌等低成本方式优化。测试示例:

vector<int> vSource = {1,2,3,4,5,6,7,8,9,10,11,12,13};
vector<int> vInd = {2,1,5,3,10,5,8,2,10,2,5,3};
// 期望输出:3   2   6   4   11  6   9   3

现有实现问题

已通过AVX2 intrinsics实现向量化,但VCL的模板版本gather8i仅支持编译时常量索引,无法传入运行时动态索引:

AVX2 intrinsics 可行实现

void intrinGather(vector<int> & vSource, vector <int> & vInd) {
    __m256i ind = _mm256_loadu_si256((__m256i*) &vInd[0]);
    __m256i vec = _mm256_i32gather_epi32(&vSource[0], ind, 4);
}

VCL 模板版本的局限

void VCLGather(vector<int> & vSource, vector<int> ind) {
    Vec8i vec;
    vec=gather8i<2,1,5,3,10,5,8,2>(&vSource[0]); // 编译通过
    // vec=gather8i<ind[0],ind[3],ind[2],ind[10],ind[6],ind[8],ind[7],ind[1]>(&vSource[0]); // 编译失败
}

解决方案:VCL动态索引Gather接口

VCL提供了支持运行时动态索引的Gather接口,无需依赖编译时常量模板参数,同时保留VCL的多架构兼容特性。以AVX2对应的Vec8i为例,实现代码如下:

#include <VCL/Vec8i.h>
#include <vector>

void VCLDynamicGather(std::vector<int>& vSource, std::vector<int>& vInd) {
    // 按向量宽度(8个int)批量处理索引
    size_t batchCount = vInd.size() / 8;
    for (size_t i = 0; i < batchCount; ++i) {
        // 加载8个动态索引到VCL向量
        Vec8i indices = Vec8i::loadu(&vInd[i * 8]);
        // 执行Gather操作,步长为4(int类型的字节数)
        Vec8i result = Vec8i::gather(&vSource[0], indices, 4);
        
        // 对结果执行后续操作,例如存储或计算
        // result.storeu(...);
    }
    
    // 处理剩余不足8个的元素
    size_t remaining = vInd.size() % 8;
    for (size_t i = batchCount * 8; i < vInd.size(); ++i) {
        int val = vSource[vInd[i]];
        // 剩余元素的串行处理逻辑
    }
}

关键说明

  1. 动态索引支持:VCL向量类型(如Vec8i)的gather静态成员函数,接收同类型的向量索引参数,支持运行时加载的动态索引,逻辑与AVX2 intrinsics的_mm256_i32gather_epi32一致,但封装为VCL风格接口。
  2. 多架构兼容:该写法会自动适配VCL支持的指令集(SSE/AVX/AVX2等),编译时根据目标架构生成对应指令,无需手动区分。
  3. 内存对齐优化:若vSource或vInd是对齐内存,可替换loadu/storeu为load/store提升性能;不确定对齐情况时,loadu/storeu更安全。
  4. 剩余元素处理:实际场景中需处理索引数量非向量宽度倍数的情况,剩余元素可通过串行循环或更小的向量类型(如Vec4i)处理。

验证效果

使用用户提供的测试数据调用VCLDynamicGather,第一个向量块的result值为{3,2,6,4,11,6,9,3},与期望输出一致。

内容的提问来源于stack exchange,提问作者Vladislav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:07:37