多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

CPU架构名词全解析:X86、X64、ARM、AArch64一次搞懂

CPU架构名词全解析:X86、X64、ARM、AArch64一次搞懂 1. 从一个让人头大的报错说起如果你在开发过程中遇到过下面这些报错那你一定对今天要聊的话题不陌生模块计算机类型x86与目标计算机类型x64冲突 npm : 无法加载文件 D:\Program Files (x86)\nodejs\npm.ps1因为在此系统上禁止运行脚本 error: command ...\amd64\cl.exe failed with exit status 2 cannot find a valid baseurl for repo: base/7/x86_64这些报错看起来五花八门有的跟 Node.js 有关有的跟 Python 编译有关有的跟 Linux 包管理有关但它们背后其实都指向同一件事——CPU 架构和软件架构的匹配问题。X86、X64、X86_64、AMD64、i386、ARM、ARM64、AArch64……这些名词经常混在一起出现有时候同一个东西有好几个名字有时候看起来差不多的名字却是完全不同的东西。很多人在下载软件、配置编译环境、拉取 Docker 镜像的时候面对一堆架构选项直接懵了我到底该选哪个这篇文章就是要把这些名词彻底理清楚。不管你是刚入行的开发新手还是经常跟交叉编译打交道的老手我都会从实际使用场景出发把每个概念讲透把容易混淆的地方掰开揉碎再配上真实的踩坑案例和选择建议。看完之后你至少能做到看到任何一个架构名词立刻知道它指的是什么、用在什么场景、跟你手头的机器是否匹配。2. 先把 CPU 指令集这层窗户纸捅破2.1 指令集到底是什么为什么它决定了一切CPU 说到底就是一个执行指令的机器。它认识的那些命令的集合就叫指令集架构Instruction Set Architecture简称 ISA。你可以把它理解成 CPU 的母语——不同架构的 CPU 说的是不同的语言X86 架构的 CPU 听不懂 ARM 的指令反过来也一样。这个类比很关键。当你下载一个软件的时候本质上你下载的是一堆编译好的机器指令。如果这些指令是给 X86 CPU 写的你拿到 ARM 机器上就跑不了因为 ARM 根本看不懂。这就是为什么下载页面总是让你选架构——它得知道给你发哪个语言版本的软件包。指令集架构决定了软件生态的底层兼容性。一个操作系统、一个编译器、一个运行时环境全都要针对特定的指令集来构建。这也是为什么 ARM 版的软件生态和 X86 版的软件生态长期是两条平行线虽然近年来在逐步融合但底层的差异始终存在。2.2 CISC 和 RISC两条不同的设计哲学X86 家族属于CISCComplex Instruction Set Computing复杂指令集计算。它的特点是单条指令能做的事情比较多指令数量庞大编码长度可变。这种设计的好处是编程方便一条指令可能顶 RISC 的好几条缺点是硬件解码复杂功耗相对较高。ARM 家族属于RISCReduced Instruction Set Computing精简指令集计算。它的特点是指令长度固定、数量精简、每条指令做的事情相对简单。好处是硬件设计简洁、功耗低、适合流水线执行缺点是完成同样的任务可能需要更多条指令。这个差异直接导致了两者在不同场景下的优势X86 在桌面和服务器领域凭借强大的单核性能和成熟的生态占据主导ARM 在移动设备和嵌入式领域凭借低功耗和高能效比称霸。当然现在这个界限已经越来越模糊了——ARM 在服务器领域发力X86 也在往低功耗方向走但底层的架构差异依然存在。2.3 位数32 位和 64 位到底差在哪里除了指令集的设计哲学还有一个维度是位数。32 位和 64 位最核心的区别在于寄存器宽度和内存寻址能力。32 位架构的寄存器宽度是 32 位能直接寻址的内存空间上限是 2 的 32 次方也就是 4GB。实际上操作系统还会预留一部分给硬件映射所以用户程序能用到的通常只有 3GB 左右。这就是为什么早年 32 位 Windows 明明装了 8GB 内存却只认 3GB 多。64 位架构的寄存器宽度是 64 位理论寻址空间是 2 的 64 次方这个数字大到目前完全用不完。实际实现中目前主流的 64 位处理器通常使用 48 位或 57 位物理地址线但即便如此支持的内存容量也远远超过 32 位的 4GB 上限。除了内存寻址64 位架构还有更多通用寄存器、更宽的整数运算能力、更高效的函数调用约定等优势。这些改进让 64 位程序在计算密集型任务上通常比 32 位版本快不少。3. X86 家族族谱i386、X86_64、AMD64 到底是什么关系3.1 i386一切故事的起点i386指的是 Intel 80386 处理器这是 Intel 在 1985 年推出的第一款 32 位 X86 处理器。在软件包的命名里i386 通常代表32 位 X86 架构这个大类。你可能会看到 i386、i486、i586、i686 这些名字它们分别对应不同世代的 Intel 处理器但在现代软件命名中它们基本上都泛指 32 位 X86。在 Debian/Ubuntu 的软件源里你会看到i386这个架构标识它代表的就是 32 位版本。在 RPM 包命名里你也会看到.i386.rpm、.i686.rpm这样的后缀。简单记看到 i386 或 i686基本就是 32 位 X86。3.2 X86_64 和 AMD64同一个东西的两个名字这里是最容易让人困惑的地方。X86_64和AMD64指的是同一个东西——64 位 X86 架构。那为什么会有两个名字故事是这样的Intel 最早尝试推广 64 位架构时搞了一个叫 Itanium 的东西用的是全新的 IA-64 指令集跟原来的 X86 不兼容。市场反应很差。而 AMD 在 Intel 之前就搞出了一个兼容 X86 的 64 位扩展方案叫 AMD64。这个方案既能跑 64 位新程序又能兼容原来的 32 位程序市场接受度很高。后来 Intel 也不得不跟进采纳了 AMD 的这套方案但给它起了个名字叫 EM64T 或者 Intel 64。所以本质上AMD64 是这项技术的原始名称X86_64 是更中性的叫法。在不同的软件生态里你看到的名称不一样Linux 世界尤其是 Debian/Ubuntu通常叫amd64Linux 世界尤其是 RPM 系通常叫x86_64Windows 世界通常叫x64macOS 世界通常叫x86_64BSD 世界通常叫amd64它们说的都是同一件事64 位 X86 架构。你下载软件的时候看到 amd64 和 x86_64不用犹豫选哪个都行它们在你的 Intel 或 AMD 机器上都能跑。3.3 X64Windows 阵营的简写X64基本上是 Windows 生态里对 X86_64 的简写。微软在命名下载包、系统版本、运行时库的时候大量使用 x64 这个标识。比如Microsoft Visual C 2019 Redistributable Package (x64)、Windows 11 Enterprise LTSC 2024 (x64)。需要注意的是x64 和 x86_64 在绝大多数语境下是可以互换的但严格来说 x64 更多出现在 Windows 相关的场景中。如果你在 Linux 的软件源里看到 x64 这个标识那通常是非标准写法但意思一样。3.4 一张表理清 X86 家族的所有别名名称含义常见出现场景i38632 位 X86Debian/Ubuntu 软件源、RPM 包名i68632 位 X86较新世代RPM 包名、部分 Linux 发行版x8632 位 X86 的统称Windows 程序目录、环境变量X86_6464 位 X86Linux 通用、macOSamd6464 位 X86Debian/Ubuntu、FreeBSDx6464 位 X86Windows 生态EM64T / Intel 6464 位 X86Intel 官方文档记住一个原则32 位和 64 位是两回事但 64 位的那些名字X86_64、AMD64、x64都是同一个东西。4. ARM 阵营从手机到服务器的全面扩张4.1 ARM 的命名体系为什么这么乱ARM 的命名比 X86 还要复杂因为它涉及的场景更多、授权模式更灵活。ARM 公司本身不生产芯片它设计指令集架构和核心方案然后授权给各家芯片厂商高通、苹果、三星、华为等去生产具体芯片。这就导致了同一个架构在不同厂商那里可能有不同的叫法。从大的版本来看ARM 架构经历了 ARMv7、ARMv8、ARMv9 等世代。ARMv7 是 32 位时代的代表ARMv8 开始引入 64 位支持ARMv9 是最新一代。但在软件包的命名里你看到的通常不是版本号而是下面这些标识。4.2 ARM、ARM64、AArch64 的区别ARM这个词在不同语境下含义不同。在软件包命名里单独的arm或armhf、armel通常指32 位 ARM 架构。armhf表示带硬件浮点支持的 32 位 ARMarmel表示软浮点的 32 位 ARM。现在绝大多数 ARM 设备都支持硬件浮点所以armhf更常见。ARM64指的是64 位 ARM 架构。这是目前最主流的叫法尤其在移动端和嵌入式领域。AArch64是 ARMv8-A 架构中 64 位执行状态的正式名称。在 Linux 内核和一些底层工具链里你会看到aarch64这个标识。它和 ARM64 指的是同一个东西只是叫法更学术一些。在 Debian/Ubuntu 的软件源里64 位 ARM 通常叫arm64在 RPM 系里可能叫aarch64在 Windows on ARM 的场景里微软通常叫ARM64。它们说的都是同一件事。4.3 ARM 和 RISC-V新老交替还是各走各路近年来RISC-V作为一个开源指令集架构越来越受关注。它和 ARM 同属 RISC 阵营但最大的区别在于 RISC-V 是完全开放免费的任何人都可以用它设计芯片不需要支付授权费。ARM 则是商业授权模式用它的架构要交钱。从软件生态角度看ARM 目前远远领先于 RISC-V尤其是在移动端和服务器领域。但 RISC-V 在嵌入式、物联网、教学科研等场景增长很快。对于普通开发者来说短期内主要打交道的还是 ARM 和 X86 两大阵营RISC-V 可以保持关注但暂时不用太焦虑。4.4 ARM 生态的实际使用场景ARM 架构在实际开发和运维中出现的频率越来越高主要集中在这几个场景移动端开发Android 和 iOS 设备全部是 ARM 架构移动应用的 native 库必须编译 ARM 版本嵌入式与物联网树莓派、各种开发板、智能设备基本都是 ARM服务器AWS Graviton、阿里云倚天、华为鲲鹏等 ARM 服务器逐渐普及桌面苹果 M 系列芯片让 ARM 桌面进入主流视野Windows on ARM 也在推进Docker 镜像多架构镜像越来越常见拉取镜像时需要注意架构匹配5. 实战中最容易踩的架构坑5.1 Windows 上的 Program Files (x86) 到底是怎么回事在 64 位 Windows 上你会看到两个程序目录C:\Program Files和C:\Program Files (x86)。这不是微软随便起的名字而是有明确含义的C:\Program Files存放64 位程序C:\Program Files (x86)存放32 位程序这样设计是为了兼容性。64 位 Windows 可以同时运行 64 位和 32 位程序但为了避免文件冲突比如 32 位和 64 位版本的同名程序需要不同的 DLL系统把它们分开存放。这个设计带来的一个常见坑是环境变量 PATH 里可能同时存在 32 位和 64 位的工具路径导致版本冲突。比如你装了 32 位的 Node.js 和 64 位的 Python在某些情况下可能会出现调用混乱。排查这类问题时第一步就是确认你调用的到底是哪个目录下的可执行文件。5.2 npm 脚本执行被禁止PowerShell 执行策略的坑npm : 无法加载文件 D:\Program Files (x86)\nodejs\npm.ps1因为在此系统上禁止运行脚本这个报错跟架构没有直接关系但经常和架构问题混在一起出现。原因是 PowerShell 默认的执行策略不允许运行脚本文件。解决方法是以管理员身份打开 PowerShell执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser或者改用 CMD 来执行 npm 命令。这个坑之所以值得提是因为报错信息里出现了Program Files (x86)容易让人误以为是架构问题实际上是执行策略问题。5.3 Python 编译扩展时的 amd64 报错error: command C:\Users\...\amd64\cl.exe failed with exit status 2这个报错通常出现在 Windows 上安装需要编译的 Python 包时。cl.exe是 MSVC 编译器路径里的amd64表示它在调用 64 位编译器。报错的原因可能是没有安装对应版本的 Visual C Build Tools安装了但环境变量没配置好Python 是 32 位的但编译器是 64 位的或反过来排查思路先确认 Python 的位数python -c import platform; print(platform.architecture())再确认编译器的位数两者必须匹配。5.4 Docker 拉取镜像时的架构选择docker pull rustfs x86_64 哪个版本Docker 镜像现在很多都是多架构的multi-archdocker pull会自动根据当前机器的架构拉取对应版本。但如果你在 ARM 机器上拉一个只有 x86_64 版本的镜像就会报错或者通过模拟层运行性能很差。查看镜像支持哪些架构docker manifest inspect 镜像名:标签强制指定架构拉取docker pull --platform linux/amd64 镜像名:标签 docker pull --platform linux/arm64 镜像名:标签在 ARM 服务器上跑 x86 镜像虽然可行通过 QEMU 模拟但性能损失可能达到数倍生产环境慎用。5.5 Linux 包管理的架构标识在 CentOS/RHEL 系里你会看到这样的报错cannot find a valid baseurl for repo: base/7/x86_64这里的x86_64表示系统在找 64 位 X86 的软件源。如果这个源配置有问题比如镜像地址失效、网络不通就会报这个错。解决方法是检查/etc/yum.repos.d/下的 repo 文件确认 baseurl 指向的地址是否可访问。在 Debian/Ubuntu 系里对应的架构标识是amd64。你可以用dpkg --print-architecture查看当前系统的架构。6. 怎么快速判断和选择正确的架构6.1 查看当前机器的架构不同系统下查看架构的命令Linuxuname -m输出可能是x86_64、aarch64、armv7l等。macOSuname -mApple Silicon 机器输出arm64Intel 机器输出x86_64。WindowsPowerShell$env:PROCESSOR_ARCHITECTURE输出可能是AMD64、ARM64、x86等。WindowsCMDecho %PROCESSOR_ARCHITECTURE%Python跨平台import platform print(platform.machine()) print(platform.architecture())6.2 下载软件时的选择决策树面对一个下载页面按这个顺序判断先确认你的机器架构用上面的命令查一下再看操作系统Windows、Linux、macOS 各有不同的命名习惯匹配命名你的机器是 x86_64/amd64就选 x64、x86_64、amd64 这些标识你的机器是 ARM64/aarch64就选 arm64、aarch64 这些标识你的机器是 32 位 X86就选 x86、i386、i686 这些标识不确定就选 64 位现在绝大多数场景下 64 位是正确选择6.3 交叉编译场景下的架构指定在做交叉编译时比如在 x86 机器上编译 ARM 程序需要显式指定目标架构。以 GCC 为例# 编译 32 位程序在 64 位机器上 gcc -m32 -o output source.c # 编译 64 位程序 gcc -m64 -o output source.c # 交叉编译 ARM64 aarch64-linux-gnu-gcc -o output source.c在 CMake 里指定目标架构set(CMAKE_C_FLAGS -m64)在 Go 里交叉编译GOARCHarm64 GOOSlinux go build -o output GOARCHamd64 GOOSwindows go build -o output.exe6.4 常见软件包的架构命名对照软件生态32 位 X8664 位 X8664 位 ARMDebian/Ubuntui386amd64arm64RHEL/CentOSi686x86_64aarch64Windowsx86x64ARM64macOS-x86_64arm64Go386amd64arm64Rusti686x86_64aarch64Dockerlinux/386linux/amd64linux/arm64这张表建议收藏下次下载软件或者配置编译环境的时候直接对照能省掉大量试错时间。7. 几个真实场景的完整排查记录7.1 场景一在 ARM 服务器上跑 x86 Docker 镜像有一次在 ARM 服务器上部署一个服务docker pull之后容器启动就挂。查看日志发现是exec format error。原因很明确镜像只有 x86_64 版本ARM 机器直接跑不了。解决方案有两个一是找 ARM 版本的镜像二是通过--platform linux/amd64强制拉取 x86 版本并依赖模拟层运行。第一种方案性能正常第二种方案能用但性能打折扣。最终选择了找 ARM 版本的基础镜像自己重新构建。这个经历告诉我在 ARM 环境做容器化部署第一步就是确认所有基础镜像都有 ARM 版本。没有的话要么换镜像要么做好性能损失的准备。7.2 场景二Windows 上 Python 包安装失败一个同事在 Windows 上装某个科学计算包一直报cl.exe failed with exit status 2。排查过程确认 Python 版本64 位 Python 3.9确认编译器系统里装的是 32 位的 Visual C Build Tools结论位数不匹配解决方法是卸载 32 位 Build Tools安装 64 位版本。或者更省事的办法直接找这个包的预编译 wheel 文件.whl避免本地编译。7.3 场景三CentOS 7 的 yum 源架构问题一台老 CentOS 7 机器yum install任何东西都报cannot find a valid baseurl for repo: base/7/x86_64。排查uname -m确认是 x86_64架构没问题检查/etc/yum.repos.d/CentOS-Base.repo发现 mirrorlist 指向的地址已经失效替换为 vault 地址CentOS 7 已停止维护需要指向 vault 源修改后的 repo 配置指向mirrors.tuna.tsinghua.edu.cn/centos-vault/7.9.2009/下的对应目录问题解决。这个案例说明架构标识本身没问题但软件源地址可能因为版本停止维护而失效。看到架构相关的报错不要只盯着架构也要检查源配置。7.4 场景四Node.js 的 32 位与 64 位混装有台 Windows 机器上同时装了 32 位和 64 位的 Node.js导致npm命令行为诡异。排查where node查看实际调用的路径发现 PATH 里 32 位路径排在前面清理 PATH只保留一个版本的 Node.js这个坑的教训是Windows 上安装开发工具时注意检查 PATH 环境变量避免多版本冲突。尤其是Program Files和Program Files (x86)两个目录下都装了同名工具的情况。8. 我个人的一些经验总结折腾了这么多年架构相关的问题有几个心得值得分享。第一养成先查架构的习惯。不管是下载软件、拉取镜像、配置编译环境第一步永远是确认目标平台的架构。这个动作只需要几秒钟但能避免后面大量的试错。第二不要被名字迷惑。X86_64、AMD64、x64 是同一个东西ARM64、AArch64 是同一个东西。看到不认识的架构名先查一下它属于哪个家族、多少位再决定怎么处理。第三32 位生态在快速萎缩。现在新出的软件和系统越来越多只提供 64 位版本。如果你还在维护 32 位环境可能会遇到越来越多的兼容性问题。条件允许的话尽早迁移到 64 位。第四ARM 生态的成熟度在快速提升。几年前 ARM 服务器上很多软件都跑不起来现在主流的基础软件基本都有 ARM 版本了。如果你在做新项目可以考虑把 ARM 支持纳入规划。第五遇到架构相关的报错先看报错信息里的路径和标识。报错信息里通常会包含x86、amd64、aarch64这些关键词它们直接告诉你问题出在哪个环节。顺着这些线索排查比盲目搜索效率高得多。最后分享一个实用技巧在 Linux 上可以用dpkg --print-architectureDebian 系或rpm --eval %{_arch}RPM 系快速查看系统架构标识这个标识和软件源里使用的标识是一致的下载软件时直接对照即可。
返回列表