如何在AVX2中实现掩码/条件/无分支算术运算(附标量代码示例)
AVX2实现条件运算向量化方案
要实现这类条件运算的AVX2向量化,核心是利用比较指令生成掩码,再通过掩码混合指令选择对应操作数,最后完成批量乘法。以下是具体实现步骤和完整代码:
完整实现代码
#include <immintrin.h> #include <iostream> int main() { // 原数组(若要优化性能,可添加alignas(32)修饰实现32字节对齐) double arr[4] = {1.0, 2.0, 3.0, 4.0}; const double condition = 3.0; const double mul_true = 1.75; const double mul_false = 6.5; // 1. 加载数组到256位AVX2寄存器(可容纳4个double) __m256d arr_vec = _mm256_loadu_pd(arr); // 2. 将标量条件广播到256位向量(所有元素均为condition) __m256d cond_vec = _mm256_broadcast_sd(&condition); // 3. 逐元素比较arr[i] < condition,生成掩码(满足条件的位置为全1,否则全0) __m256d mask = _mm256_cmp_pd(arr_vec, cond_vec, _CMP_LT_OQ); // 4. 生成两个乘数的广播向量 __m256d mul_true_vec = _mm256_set1_pd(mul_true); __m256d mul_false_vec = _mm256_set1_pd(mul_false); // 5. 根据掩码选择乘数:满足条件选mul_true,否则选mul_false __m256d selected_mul = _mm256_blendv_pd(mul_false_vec, mul_true_vec, mask); // 6. 批量执行乘法运算 __m256d result_vec = _mm256_mul_pd(arr_vec, selected_mul); // 7. 将结果写回原数组 _mm256_storeu_pd(arr, result_vec); // 验证输出 for (double val : arr) { std::cout << val << '\t'; } std::cout << std::endl; return 0; }
关键指令说明
_mm256_loadu_pd/_mm256_storeu_pd:处理非对齐内存的加载/存储,若数组通过alignas(32)实现32字节对齐,可替换为_mm256_load_pd/_mm256_store_pd以提升性能。_mm256_broadcast_sd:将单个double标量高效广播到256位向量的所有4个元素,比通用的_mm256_set1_pd性能更优。_mm256_cmp_pd:逐元素比较两个向量,_CMP_LT_OQ参数表示“小于、非有序”(适用于无NaN的常规数值场景),返回的掩码向量中,满足条件的元素为0xFFFFFFFFFFFFFFFF(全1),否则为0x0000000000000000(全0)。_mm256_blendv_pd:根据掩码向量选择元素,当掩码元素的最高位(符号位)为1时,选择第二个源操作数(mul_true_vec)的对应元素,否则选择第一个源操作数(mul_false_vec)的元素,完美匹配条件逻辑。_mm256_mul_pd:逐元素执行批量乘法,完成最终计算。
运行上述代码后,输出结果与预期一致:1.75 3.5 19.5 26。
内容的提问来源于stack exchange,提问作者Vladislav
相关产品推荐
相关产品推荐

