x86 Intrinsics:将8个32位掩码扩展为8个64位掩码的高效方法?
高效扩展掩码并实现递增的方法
你当前通过_mm256_set_ps逐个复制掩码元素的方式效率很低,会生成大量内存加载和单元素操作指令。可以利用AVX2向量指令全程在寄存器内完成掩码扩展与递增操作,无需拆分单个元素:
最优方案:直接处理整数掩码(推荐)
浮点比较得到的__m256掩码中,每个32位元素为0x00000000(比较不成立)或0xFFFFFFFF(比较成立),直接转换为整数类型处理更高效:
// 1. 将浮点掩码转换为32位整数掩码 __m256i mask_i = _mm256_castps_si256(mask); // 2. 将全1/全0的32位值转换为0/1的增量(右移31位提取符号位) __m256i mask_32 = _mm256_srli_epi32(mask_i, 31); // 3. 将32位增量扩展为64位,对应8个64位整数的递增标记 __m256i mask_low_64 = _mm256_unpacklo_epi32(mask_32, mask_32); // 前4个64位增量 __m256i mask_high_64 = _mm256_unpackhi_epi32(mask_32, mask_32); // 后4个64位增量 // 4. 执行递增操作 values[0] = _mm256_add_epi64(values[0], mask_low_64); values[1] = _mm256_add_epi64(values[1], mask_high_64);
备选方案:仅扩展浮点掩码(若需保留浮点格式)
如果必须保持掩码为__m256格式,可用AVX2洗牌指令高效复制元素,避免逐个加载:
// 提取掩码低128位(前4个元素)并生成重复两次的掩码 __m256 half0 = _mm256_extractf128_ps(mask, 0); __m256 padded0 = _mm256_shuffle_ps(half0, half0, _MM_SHUFFLE(1,1,0,0) | (_MM_SHUFFLE(3,3,2,2) << 4)); // 提取掩码高128位(后4个元素)并生成重复两次的掩码 __m256 half1 = _mm256_extractf128_ps(mask, 1); __m256 padded1 = _mm256_shuffle_ps(half1, half1, _MM_SHUFFLE(1,1,0,0) | (_MM_SHUFFLE(3,3,2,2) << 4)); const __m256 paddedMask[2] = {padded0, padded1};
这种方式仅需几条洗牌指令,全程寄存器操作,比原代码的_mm256_set_ps高效得多。
内容的提问来源于stack exchange,提问作者allanmb
相关产品推荐
相关产品推荐

