如何用SSE/AVX/AVX2指令实现带±0.00001误差的向量相等性比较
用AVX2实现带误差范围的浮点向量相等判断
当然有简便的AVX2实现方案,核心思路是计算两个向量的差值绝对值,再和误差阈值做逐元素比较,最后验证所有元素是否都满足误差要求。
实现步骤
- 计算两个
__m256向量的差值,再取绝对值:用_mm256_sub_ps做减法,_mm256_abs_ps得到绝对值差值 - 生成一个所有元素都是误差阈值(
1e-5f,即0.00001)的AVX向量:_mm256_set1_ps(1e-5f) - 逐元素比较绝对值差值是否小于等于阈值:用
_mm256_cmp_ps,指定_CMP_LE_OQ操作符(无顺序的小于等于比较) - 将比较结果的掩码转为整数,判断是否所有位都为1:用
_mm256_movemask_ps把AVX掩码转成8位整数(对应8个单精度浮点数元素),如果结果等于0xFF,说明所有元素都在误差范围内相等
完整代码示例
#include <immintrin.h> #include <stdbool.h> bool mm256_equal_with_epsilon(__m256 a, __m256 b) { // 计算差值的绝对值 __m256 diff = _mm256_sub_ps(a, b); __m256 abs_diff = _mm256_abs_ps(diff); // 生成阈值向量 __m256 epsilon = _mm256_set1_ps(1e-5f); // 逐元素比较:abs_diff <= epsilon __m256 cmp_result = _mm256_cmp_ps(abs_diff, epsilon, _CMP_LE_OQ); // 转换为掩码,检查所有元素是否都满足条件 int mask = _mm256_movemask_ps(cmp_result); return mask == 0xFF; }
注意事项
- 如果你的向量是双精度类型(
__m256d),只需要把对应的指令替换成双精度版本:_mm256_sub_pd、_mm256_abs_pd、_mm256_set1_pd(1e-5)、_mm256_cmp_pd,掩码转换用_mm256_movemask_pd,此时判断掩码是否等于0xF(因为__m256d包含4个双精度元素) - 单精度浮点数本身的精度限制:1e-5的误差对于单精度来说是合理的,不会出现精度溢出问题
- 如果需要“所有元素满足”之外的逻辑(比如只要有一个元素满足),可以调整掩码的判断条件,比如
mask != 0
内容的提问来源于stack exchange,提问作者RandomEagle
相关产品推荐
相关产品推荐

