使用SSE/SSE2 C内建函数交换m128寄存器高32位与低32位的实现方法
实现将SSE m128寄存器最高32位移至最低位的方案
当然可以实现!在仅支持SSE/SSE2的环境下,我们可以用_mm_shuffle_ps这个内建函数直接完成寄存器内的元素重排,完美匹配你的需求。
核心思路
_mm_shuffle_ps是SSE2原生支持的混洗指令,它允许我们从一个或两个128位浮点寄存器中挑选元素,按指定顺序重新组合成新的寄存器。对于你的场景,只需要从同一个输入寄存器里挑选对应元素即可。
SSE的__m128寄存器中,4个float元素的索引是从低位到高位依次为0、1、2、3(对应你示例中的1.0f、2.0f、3.0f、4.0f)。你需要的结果是把索引3的元素移到索引0,索引0的元素移到索引3,同时保留索引1和2的元素。
代码实现
#include <xmmintrin.h> // 包含SSE/SSE2内建函数的头文件 __m128 move_high_to_low(__m128 input) { // _MM_SHUFFLE宏的参数顺序是:[目标元素3的来源索引, 目标元素2的来源索引, 目标元素1的来源索引, 目标元素0的来源索引] // 我们需要: // 目标索引0 <- 输入索引3(最高位的4.0f) // 目标索引1 <- 输入索引1(2.0f) // 目标索引2 <- 输入索引2(3.0f) // 目标索引3 <- 输入索引0(最低位的1.0f) return _mm_shuffle_ps(input, input, _MM_SHUFFLE(0, 2, 1, 3)); }
验证效果
假设输入寄存器的值是{1.0f, 2.0f, 3.0f, 4.0f},经过上述函数处理后,输出寄存器的值会变成{4.0f, 2.0f, 3.0f, 1.0f},完全符合你的预期。
为什么不使用移位指令?
你可能会考虑用_mm_slli_si128或_mm_srli_si128这类移位指令,但这些是针对整数类型的按字节移位操作。如果用左移96位(3个float的长度),虽然能把最高位的4.0f移到最低位,但原来的1.0f会被移出寄存器,变成0.0f,无法满足你把1.0f移到最高位的需求。所以混洗是更精准的选择。
内容的提问来源于stack exchange,提问作者MaxiMaxi
相关产品推荐
相关产品推荐

