为何SSE/AVX要提供针对浮点类型的and/or/xor等位运算指令?
SSE浮点位运算指令(
_mm_*_ps/_mm_*_pd)的实际使用场景 首先明确一个核心前提:这类浮点位运算指令和对应的整数_mm_*_si128指令的位运算结果完全一致,二者的差异仅体现在CPU微架构层面的执行域归属上,没有功能层面的区别。它的实际使用场景主要有三类:
- 避免向量执行域切换的性能开销
当代x86 CPU的SSE执行单元通常分为独立的浮点运算域、整数运算域,部分架构还会单独拆分位运算域。如果代码上下文正在连续处理浮点向量(全是_mm_*_ps/_mm_*_pd类指令),中间插入整数域的_mm_*_si128指令会触发域切换,带来1~3个时钟周期的额外延迟。直接使用同域的浮点位运算指令可以完全规避这个开销,在高频计算的热点代码中收益非常明显。 - 简化浮点特定位操作的代码语义
很多高频浮点操作本质就是特定位的修改,直接用浮点位运算指令不需要额外做类型转换,语义更直白:- 取浮点向量绝对值:清除最高位符号位,直接写
_mm_and_ps(vec, _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF)))即可实现 - 翻转浮点向量符号:反转最高位符号位,直接调用
_mm_xor_ps(vec, sign_mask)即可 - 合并符号与数值:从一个向量取符号位、另一个向量取数值位拼接,用
_mm_or_ps可以直接完成整个操作
- 取浮点向量绝对值:清除最高位符号位,直接写
- 兼容旧代码与旧编译器
早期SSE编程规范中没有提供_mm_castsi128_ps这类无开销的类型重解析intrinsic,开发者如果要操作浮点向量的位,要么手动做不安全的指针强转,要么直接使用浮点位运算指令。大量遗留代码至今仍在使用这类指令,保持了向下兼容性。
内容的提问来源于stack exchange,提问作者Alex Guteniev
相关产品推荐
相关产品推荐

