You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻找可交错两个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)配合位运算组合实现,步骤如下:

  1. 提取并排列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])
  2. 提取并排列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])
  3. 合并结果
    由于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:25:27