x64 与 arm64:不是“选哪个”,而是“怎么协同”——一位嵌入式系统工程师的实战手记
去年冬天,我在调试一个车载AI视觉网关时踩了个深坑:同一份YOLOv5s模型,在x64服务器上推理延迟稳定在12ms,烧录到瑞芯微RK3588(arm64)开发板后却频繁出现300ms级毛刺。perf record抓不到热点,strace看不出阻塞,连dmesg里都干干净净。最后发现,问题既不在模型,也不在驱动——而是我们沿用了x64惯用的pthread_mutex_t初始化方式,没加PTHREAD_MUTEX_ROBUST属性,而arm64弱内存序下,某个中断服务程序(ISR)中未加DMB ISH屏障,导致mutex状态在CPU核间同步失败。
那一刻我意识到:所谓“架构差异”,从来不是教科书里的对比表格,而是你凌晨三点盯着逻辑分析仪波形图时,突然理解为什么ldar和stlr必须成对出现;是你在给飞腾D2000写BSP时,发现mrs x0, cntfrq_el0返回0,才翻到ARM ARM文档第D1.12.2节那句轻描淡写的注释:“The frequency is IMPLEMENTATION DEFINED and may be zero if not configured by firmware.”
所以这篇文字不叫“区别详解”,它是一份带着焊锡味和示波器余温的现场笔记——没有总-分-总套路,只有真实项目里撞过的墙、调通的寄存器、改过的Makefile。
从第一条指令开始:启动那一刻,它们就走上了不同道路
x64开机第一件事,是跳进实模式,执行BIOS/UEFI里一段16位x86代码,靠段寄存器拼出物理地址。这个设计源于1978年8086——为了兼容更老的8080。而arm64上电瞬间,CPU直接进入AArch64异常级别EL3(Secure Monitor),从0x0或0xffff000000000000(取决于SCR_EL3.RW)取第一条指令。它不认汇编里的mov ax, bx,因为压根没有ax、bx这种命名;它的通用寄存器叫x0到x30,连栈指针都叫sp_el3,明明白白告诉你:“我在哪一级特权下运行”。
这不只是命名差异。这意味着:
- 在x64上,你可以用cli/sti关开中断,但这是个危险操作——现代CPU早已把中断屏蔽逻辑移到APIC,sti只是给APIC发个信号;
- 而在arm64上,关中断必须写daifset系统寄存器(msr daifset, #2),且这个操作本身不可被抢占——硬件强制保证其原子性。
工程师笔记:我们在做某款国产工控PLC固件时,曾把x64裸机驱动里的
__disable_irq()直接移