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

如何用SSE指令零扩展加载uint8_t至XMM0实现SIMD浮点乘法?

解决方案:将4个uint8_t加载到XMM0并清零高24位后执行SIMD乘法

要实现需求,核心是把8位无符号整数零扩展为32位整数,再转换为单精度浮点数,才能和XMM1中的float数组执行SIMD乘法。以下是两种可行方案:

推荐方案:使用SSE4.1指令pmovzxbd

pmovzxbd是专门为这类场景设计的指令,直接完成4个uint8_t零扩展为32位整数的操作,代码简洁高效:

; 从RDI指向的内存加载4个uint8_t,每个零扩展到32位,存入XMM0的4个双字位置
pmovzxbd xmm0, [rdi]  
; 将XMM0中的32位整数转换为单精度float
cvtdq2ps xmm0, xmm0   
; 与XMM1中的4个float执行SIMD乘法
mulps xmm0, xmm1      

指令说明:pmovzxbd的命名规则里,z代表零扩展(Zero-Extend),b表示源操作数是8位字节(uint8_t),d表示目标是32位双字,完美匹配需求。

兼容方案:无SSE4.1支持时的替代实现

如果运行环境不支持SSE4.1,可以用SSE2的pshufb(字节洗牌)指令组合实现:

; 先加载4个uint8_t到XMM0的低4字节
movd xmm0, [rdi]      
; 定义掩码:让每个uint8_t对应到双字的低8位,其余字节清零
section .data
mask db 0x00, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80
     db 0x02, 0x80, 0x80, 0x80, 0x03, 0x80, 0x80, 0x80

; 加载掩码到XMM2
movdqa xmm2, [mask]   
; 执行字节洗牌:将原uint8_t放到对应双字的低8位,高24位清零
pshufb xmm0, xmm2     
; 转换为float后执行乘法
cvtdq2ps xmm0, xmm0   
mulps xmm0, xmm1      

关于movdqu的问题

你之前尝试的movdqu xmm0, [rdi]只是把16个uint8_t原封不动加载到XMM0,没有做任何扩展操作。此时XMM0中是16个8位值,无法直接和XMM1的32位float执行mulps(操作数类型不匹配),必须先完成零扩展和浮点转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:16:20