ARM CPU的 intrinsics指令集 - svindex_u32
基本语法
svuint32_t svindex_u32(uint32_t start);
参数与返回值
核心功能
使用场景与示例
场景:从数组中按连续索引加载元素并计算总和(模拟向量级循环访问)。
#include <arm_sve.h> #include <stdint.h> // 计算数组中从start_idx开始的n个元素的和 uint64_t sum_range(const uint32_t* arr, size_t start_idx, size_t n) { uint64_t total = 0; size_t i = 0; svcount_t vl = svcntw(); // 获取32位元素的向量长度(如8) while (i < n) { // 计算当前批次的实际元素数(不超过剩余元素和向量长度) size_t remaining = n - i; svcount_t current_vl = svmin_u32(vl, remaining); svbool_t pg = svwhilelt_b32(0, current_vl); // 掩码:标记当前批次有效元素 // 生成当前批次的索引:[start_idx + i, start_idx + i + 1, ...] svuint32_t indices = svindex_u32((uint32_t)(start_idx + i)); // 按索引加载元素(连续索引可直接用svld1,此处演示索引用法) svuint32_t vec = svld1_u32(pg, arr + start_idx + i); // 累加当前批次元素的和 total += svaddv_u32(pg, vec); // 更新循环变量 i += current_vl; } return total; } // 调用示例: // uint32_t arr[] = {10, 20, 30, 40, 50, 60, 70, 80}; // uint64_t sum = sum_range(arr, 2, 5); // 计算索引2~6的元素和:30+40+50+60+70 = 250
进阶用法:配合 gather 指令访问非连续索引
// 访问数组中间隔为2的元素(索引0,2,4,...) void access_strided(const uint32_t* arr, size_t len, uint32_t* result) { size_t i = 0; svcount_t vl = svcntw(); while (i < len) { svcount_t current_vl = svmin_u32(vl, len - i); svbool_t pg = svwhilelt_b32(0, current_vl); // 生成基础索引 [i, i+1, ..., i+current_vl-1] svuint32_t base_indices = svindex_u32((uint32_t)i); // 计算间隔为2的索引:base_indices * 2 svuint32_t strided_indices = svmul_u32_z(pg, base_indices, 2); // 按计算出的索引加载元素(非连续访问,需用gather指令) svuint32_t vec = svld1_gather_u32index_u32(pg, arr, strided_indices); // 存储结果 svst1_u32(pg, result + i, vec); i += current_vl; } }