AVX/AVX2寄存器与两个SSE/SSE2寄存器最高效拆分拼接实现方法问询
AVX与SSE寄存器互转最优实现解答
现有float场景代码的优化空间
你提供的float场景实现已经达到了后端执行效率的理论上限,仍有微小的优化空间:
- 所有
_mm256_castxxx类操作都是编译期的类型重解释,不会生成任何实际运行的CPU指令,仅做寄存器类型的语义转换,零开销。 - 原代码中用到的
_mm256_permute2f128_ps是单微指令,延迟约3周期,吞吐量1周期/条,已经是跨128位lane搬运数据的最低开销指令。你可以改用专门的提取/插入指令替换permute指令,代码可读性更高,生成的指令编码短2字节,前端解码和iCache占用更优,后端执行效率完全一致:
__m128 avx_to_sse_ps(__m256 a, __m128 * hi) { *hi = _mm256_extractf128_ps(a, 1); return _mm256_castps256_ps128(a); } __m256 sse_to_avx_ps(__m128 a, __m128 b) { __m256 tmp = _mm256_castps128_ps256(a); return _mm256_insertf128_ps(tmp, b, 1); }
双精度浮点数(double)场景实现
逻辑和float场景完全一致,仅替换对应向量类型和内置函数即可,最优实现如下:
// 拆分256位double向量,返回低128位,高128位写入输出指针 __m128d avx_to_sse_pd(__m256d a, __m128d * hi) { *hi = _mm256_extractf128_pd(a, 1); return _mm256_castpd256_pd128(a); } // 拼接两个128位double向量,低128位为a,高128位为b __m256d sse_to_avx_pd(__m128d a, __m128d b) { __m256d tmp = _mm256_castpd128_pd256(a); return _mm256_insertf128_pd(tmp, b, 1); }
整数场景实现
逻辑和浮点场景完全一致,注意整数版本的提取/插入指令需要AVX2指令集支持,最优实现如下:
// 拆分256位整数向量,返回低128位,高128位写入输出指针 __m128i avx_to_sse_si256(__m256i a, __m128i * hi) { *hi = _mm256_extractf128_si256(a, 1); return _mm256_castsi256_si128(a); } // 拼接两个128位整数向量,低128位为a,高128位为b __m256i sse_to_avx_si256(__m128i a, __m128i b) { __m256i tmp = _mm256_castsi128_si256(a); return _mm256_insertf128_si256(tmp, b, 1); }
如果需要兼容仅支持AVX(无AVX2)的CPU,整数场景可以将整数向量转为浮点向量执行permute操作再转回,仅多两次零开销的类型cast,性能损失可以忽略。
内容的提问来源于stack exchange,提问作者Arty
相关产品推荐
相关产品推荐

