ARM CPU的 intrinsics指令集 - svsel_u32
基本语法
svuint32_t svsel_u32( svbool_t pg, // 选择掩码:决定元素来源 svuint32_t then_vec, // 当掩码位为1时,选择该向量的元素 svuint32_t else_vec // 当掩码位为0时,选择该向量的元素 );
参数说明
核心功能
使用场景与示例
场景:将数组中大于阈值的元素保留原值,小于等于阈值的元素替换为 0(即 “截断” 低阈值元素)。
#include <arm_sve.h> #include <stdint.h> // 处理数组:元素>threshold则保留,否则置0 void threshold_filter(uint32_t* dst, const uint32_t* src, size_t len, uint32_t threshold) { size_t i = 0; svcount_t vl = svcntw(); // 获取32位元素的向量长度(如8) svbool_t pg = svwhilelt_b32(i, len); // 初始掩码:标记有效元素 // 广播阈值到向量(用于比较) svuint32_t threshold_vec = svdup_u32(threshold); while (svptest_any(svptrue_b32(), pg)) { // 加载源向量 svuint32_t src_vec = svld1_u32(pg, src + i); // 比较:src_vec[i] > threshold_vec[i],生成选择掩码 svbool_t greater_mask = svcmpgt_u32(pg, src_vec, threshold_vec); // 生成全0向量(用于替换小于等于阈值的元素) svuint32_t zero_vec = svdup_u32(0); // 选择:greater_mask为1时保留src_vec元素,否则选择0 svuint32_t dst_vec = svsel_u32(greater_mask, src_vec, zero_vec); // 存储结果 svst1_u32(pg, dst + i, dst_vec); // 更新循环变量 i += vl; pg = svwhilelt_b32(i, len); } } // 调用示例: // uint32_t src[] = {15, 5, 25, 8, 30, 12}; // uint32_t dst[6]; // threshold_filter(dst, src, 6, 10); // 结果:[15, 0, 25, 0, 30, 12]
进阶用法:结合多个掩码的复杂选择
若需根据多个条件进行选择,可通过组合掩码实现。例如,将数组元素按范围分为 “低、中、高” 三档并替换为对应值:
// 将元素分为三档:<10→0,10~20→1,>20→2 void categorize(uint32_t* dst, const uint32_t* src, size_t len) { // ...(循环框架同上) svuint32_t src_vec = svld1_u32(pg, src + i); // 生成两个条件掩码 svbool_t lt10 = svcmplt_u32(pg, src_vec, svdup_u32(10)); // <10 svbool_t gt20 = svcmpgt_u32(pg, src_vec, svdup_u32(20)); // >20 // 先按>20选择2或中间值(1) svuint32_t temp = svsel_u32(gt20, svdup_u32(2), svdup_u32(1)); // 再按<10选择0或temp(即1或2) svuint32_t dst_vec = svsel_u32(lt10, svdup_u32(0), temp); // ...(存储结果) }