在 ARM SVE(Scalable Vector Extension) intrinsics 指令集中,svminv_u32 是无符号 32 位整数向量的最小值缩减指令,用于计算向量中所有有效元素的最小值(“v” 表示 “vector reduction”,即向量缩减操作)。它能高效地从批量数据中提取最小值,适用于统计分析、阈值计算、数据归一化等场景。
uint32_t svminv_u32(
svbool_t pg, // 掩码:指示哪些元素参与最小值计算
svuint32_t vec // 待计算最小值的无符号32位整数向量
);
-
pg(predicate mask)
类型为 svbool_t 的掩码向量,用于标记向量中哪些元素参与最小值计算。只有掩码位为1的元素会被纳入计算,掩码位为0的元素会被忽略。
-
vec
类型为 svuint32_t 的 SVE 向量,存储待计算最小值的无符号 32 位整数元素。向量长度由当前硬件的 SVE 宽度决定(如 256 位向量可容纳 8 个 32 位元素)。
返回一个 uint32_t 类型的标量值,即向量 vec 中所有被 pg 掩码标记为有效的元素的最小值。若掩码中没有有效元素(全为0),返回值未定义(实际使用中需避免此情况)。
svminv_u32 的核心是对向量中有效元素执行 “缩减” 操作,即从所有参与计算的元素中找出最小值。它相当于标量循环中的 “遍历所有元素并记录最小值”,但通过 SVE 硬件加速实现并行计算,效率更高。
- 示例:
假设向量长度为 4,
- 掩码
pg = [1, 1, 0, 1](仅第 0、1、3 位有效),
vec = [15, 8, 20, 5],
则参与计算的元素为 15、8、5,最小值为 5,故返回 5。
svminv_u32 常用于需要从批量数据中快速获取最小值的场景,如统计数组中的最小值、过滤异常值、动态调整阈值等。以下是一个实际应用示例:
#include <arm_sve.h>
#include <stdint.h>
#include <stddef.h>
// 计算数组中所有元素的最小值
uint32_t array_min(const uint32_t* arr, size_t len) {
if (len == 0) return 0; // 处理空数组(根据业务定义)
size_t i = 0;
svcount_t vl = svcntw(); // 获取32位元素的向量长度(如8)
svbool_t pg = svwhilelt_b32(i, len); // 初始掩码:标记有效元素
// 加载第一批元素并初始化当前最小值
svuint32_t vec = svld1_u32(pg, arr + i);
uint32_t current_min = svminv_u32(pg, vec);
// 迭代处理剩余元素
i += vl;
pg = svwhilelt_b32(i, len);
while (svptest_any(svptrue_b32(), pg)) {
vec = svld1_u32(pg, arr + i);
// 计算当前批次的最小值,并与全局最小值比较
uint32_t batch_min = svminv_u32(pg, vec);
current_min = (batch_min < current_min) ? batch_min : current_min;
i += vl;
pg = svwhilelt_b32(i, len);
}
return current_min;
}
// 调用示例:
// uint32_t arr[] = {12, 5, 23, 8, 3, 19};
// uint32_t min_val = array_min(arr, 6); // 结果:3
若需先筛选出满足特定条件的元素,再计算它们的最小值(如求数组中大于 10 的元素的最小值),可结合比较指令与 svminv_u32 实现:
// 计算数组中 > threshold 的元素的最小值
uint32_t min_greater_than(const uint32_t* arr, size_t len, uint32_t threshold) {
if (len == 0) return 0;
size_t i = 0;
svcount_t vl = svcntw();
svbool_t pg = svwhilelt_b32(i, len);
svuint32_t threshold_vec = svdup_u32(threshold);
// 初始化:先找到第一批中>threshold的元素的最小值
svuint32_t vec = svld1_u32(pg, arr + i);
svbool_t greater_mask = svcmpgt_u32(pg, vec, threshold_vec);
uint32_t current_min = svminv_u32(greater_mask, vec);
i += vl;
pg = svwhilelt_b32(i, len);
while (svptest_any(svptrue_b32(), pg)) {
vec = svld1_u32(pg, arr + i);
greater_mask = svcmpgt_u32(pg, vec, threshold_vec);
uint32_t batch_min = svminv_u32(greater_mask, vec);
// 仅当当前批次有有效元素时,更新全局最小值
if (svptest_any(svptrue_b32(), greater_mask)) {
current_min = (batch_min < current_min) ? batch_min : current_min;
}
i += vl;
pg = svwhilelt_b32(i, len);
}
return current_min;
}
-
掩码的有效性:若掩码 pg 中无有效元素(全为0),svminv_u32 的返回值未定义。实际使用中需通过 svptest_any 检查掩码有效性,避免错误。
-
无符号特性:svminv_u32 仅用于无符号 32 位整数,若需处理有符号整数,应使用 svminv_s32,两者的比较逻辑不同(无符号不考虑符号位)。
-
性能优势:相比标量循环逐个比较求最小值,svminv_u32 利用 SVE 的向量缩减硬件加速,可一次性处理多个元素(如 8 个 32 位整数),大幅提升大规模数据的处理效率。
-
与 svmin_u32 的区别:
svmin_u32 是向量间的逐元素最小值(返回向量),如 [3,5] 与 [2,6] 逐元素比较得 [2,5];
svminv_u32 是向量的缩减最小值(返回标量),如 [3,5,2,6] 缩减得 2。
svminv_u32 是 SVE 中用于计算无符号 32 位向量有效元素最小值的缩减指令,通过掩码控制参与计算的元素,高效实现批量数据的最小值提取。它在统计分析、数据过滤、阈值计算等场景中应用广泛,是发挥 SVE 向量加速能力的重要工具。