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

为何汇编代码中使用MOVUPS指令处理双精度浮点数?

关于向量化汇编中MOVUPS与MOVUPD的疑问

原C++代码

std::vector<double> a(1000000), b(1000000);  
// fill a with random doubles
for (int i = 0; i < b.size(); ++i) {  
    b[i] = a[i]*a[i] + a[i]; 
} 
std::cout << b[0] << std::endl; // make sure the compiler doesn't optimize the loop away

g++ -O3优化后的循环汇编代码

movupd  xmm1, XMMWORD PTR[rbp + 0 + rax]
movapd  xmm0, xmm1
mulpd   xmm0, xmm1
addpd   xmm0, xmm1
movups  XMMWORD PTR[r12 + rax], xmm0
add     rax, 16
cmp     rax, 8000000
jne.L17

疑问

我能理解到movups XMMWORD PTR[r12 + rax], xmm0这行之前的逻辑,该行是将a[i] * a[i] + a[i]的结果以向量化方式写回内存,但为何此处调用的是单精度的MOVUPS指令而非双精度的MOVUPD指令?

解答

其实MOVUPS和MOVUPD的核心差异仅在于CPU对内存操作的语义标记,而非实际处理的数据精度:

  • MOVUPD是针对双精度浮点数的非对齐加载/存储指令,MOVUPS是针对单精度浮点数的非对齐加载/存储指令
  • 但两者都是操作16字节的内存块(刚好容纳两个double或四个float),硬件执行时的底层操作完全一致
  • GCC这类编译器会在非对齐存储场景下优先选择MOVUPS,原因是它的指令编码长度更短(MOVUPD需要额外的前缀字节),能略微减小代码体积,同时完全不影响执行效率
  • 这里存储的是两个double值,但指令仅负责把XMM寄存器的16字节内容原封不动写入内存,不管数据类型是什么,用MOVUPS完全没问题——CPU不会因为指令后缀而改变数据的存储方式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:10:45