寻找可交错两个XMM寄存器32位块高16位的SSE指令
问题
需要使用SSE指令实现以下操作:将两个XMM寄存器a、b中每个32位块的高16位提取,按如下规则组合到结果寄存器r中:
r[15:0] = a[31:16] r[31:16] = a[63:48] r[47:32] = a[95:80] r[63:48] = a[127:112] r[79:64] = b[31:16] r[95:80] = b[63:48] r[111:96] = b[95:80] r[127:112] = b[127:112]
解决方案
没有单条SSE指令能直接完成该操作,但可以通过SSE2的_mm_shuffle_epi16(对应指令PSHUW)配合位运算组合实现,步骤如下:
提取并排列
a的目标16位块
使用_mm_shuffle_epi16从a中提取每个32位块的高16位(即a的第1、3、5、7个16位块),并将它们放到结果的低64位(第0、1、2、3个16位块):__m128i a_part = _mm_shuffle_epi16(a, 0x7531);掩码
0x7531的二进制为0111 0101 0011 0001,每个四位组指定结果对应16位块的来源:- 结果第3个16位块(
r[63:48]):取a的第7个16位块(a[127:112]) - 结果第2个16位块(
r[47:32]):取a的第5个16位块(a[95:80]) - 结果第1个16位块(
r[31:16]):取a的第3个16位块(a[63:48]) - 结果第0个16位块(
r[15:0]):取a的第1个16位块(a[31:16])
- 结果第3个16位块(
提取并排列
b的目标16位块
同理,使用_mm_shuffle_epi16从b中提取对应16位块,放到结果的高64位(第4、5、6、7个16位块):__m128i b_part = _mm_shuffle_epi16(b, 0x75310000);掩码
0x75310000指定结果高64位的16位块来源:- 结果第7个16位块(
r[127:112]):取b的第7个16位块(b[127:112]) - 结果第6个16位块(
r[111:96]):取b的第5个16位块(b[95:80]) - 结果第5个16位块(
r[95:80]):取b的第3个16位块(b[63:48]) - 结果第4个16位块(
r[79:64]):取b的第1个16位块(b[31:16])
- 结果第7个16位块(
合并结果
由于a_part的高64位为0,b_part的低64位为0,直接用位或操作合并两个部分:__m128i r = _mm_or_si128(a_part, b_part);
完整代码示例
#include <emmintrin.h> __m128i combine_high16(__m128i a, __m128i b) { __m128i a_part = _mm_shuffle_epi16(a, 0x7531); __m128i b_part = _mm_shuffle_epi16(b, 0x75310000); return _mm_or_si128(a_part, b_part); }
该方案仅依赖SSE2指令集,现代x86 CPU均支持。
内容的提问来源于stack exchange,提问作者MAP
相关产品推荐
相关产品推荐

