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

__m128i初始化与_mm_madd_epi16运算结果异常,求解释

问题原因分析

你的结果不符合预期,核心是两个错误:初始化方式错误,以及对_mm_madd_epi16的操作逻辑理解偏差。

1. __m128i初始化方式的问题

__m128i是128位向量类型,直接用{1,2,3,4,5,6,7,8}这种整数列表初始化时,编译器不会按你预期的8个16位整数填充向量。实际编译器会将列表中的每个整数当作字节(8位)填充到向量的内存中,剩余字节补0。

以你的x为例,内存布局(小端模式下)是:

字节0:0x01, 字节1:0x02, 字节2:0x03, 字节3:0x04, 字节4:0x05, 字节5:0x06, 字节6:0x07, 字节7:0x08, 字节8-15:0x00

当作为8个16位整数看待时,每个16位元素由相邻两个字节组成(小端模式下低字节在前),所以x的16位元素实际是:
[0x0201(513), 0x0403(1027), 0x0605(1541), 0x0807(2055), 0, 0, 0, 0]

同理,y的16位元素实际是:
[0x140A(5130), 0x281E(10270), 0x3C32(15410), 0x5046(20550), 0, 0, 0, 0]

2. _mm_madd_epi16的操作逻辑

_mm_madd_epi16是有符号16位乘加压缩指令,它的操作规则是:
将两个输入向量的相邻两对16位元素分别相乘,再将乘积相加,得到一个32位结果。最终输出向量包含4个32位整数(共128位)。

对应你的实际输入:

  • 第一个32位结果 = 5135130 + 102710270 = 2631690 + 10547290 = 13178980
    这个值按16位拆分(小端模式)就是低16位0x1864(6244),高16位0x00C9(201),正好是你看到的前两个元素。
  • 后续结果也是基于错误的16位元素计算而来,自然和预期不符。

正确的写法

要实现你预期的1*10 +2*20=50这类计算,需要正确初始化16位元素的向量:

// 方法1:使用_mm_set_epi16(注意参数顺序是从高到低的16位元素)
__m128i x = _mm_set_epi16(8,7,6,5,4,3,2,1);
__m128i y = _mm_set_epi16(80,70,60,50,40,30,20,10);

// 方法2:用16位数组加载
int16_t x_arr[] = {1,2,3,4,5,6,7,8};
int16_t y_arr[] = {10,20,30,40,50,60,70,80};
__m128i x = _mm_loadu_si128((__m128i*)x_arr);
__m128i y = _mm_loadu_si128((__m128i*)y_arr);

__m128i z = _mm_madd_epi16(x, y);

此时z的第一个32位元素就是1*10 +2*20=50,符合你的预期。

内容的提问来源于stack exchange,提问作者Zvi Vered

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:57:06