我有一个基于arm的(arm_v8-64,ubuntu20.04)目标机和一个基于amd的主机(x86_64,ubuntu20.04)。
由于主机上的CPU比目标上的CPU强大得多,我想知道交叉编译是否可以比本地编译更快?我的意思是基于真正的交叉编译环境(比如复制所有的arm-libs并使用相应的工具链,而不是像QEMU这样的模拟器)。
答案1
是的,交叉编译通常比在较慢的主机上本地编译要快。如果您的程序需要一分钟在 x86 上本地构建,那么您可以期望它使用 x86 托管的交叉编译器在一分钟内交叉编译到任何其他目标。
答案2
交叉编译的开销(如果有的话)也很少。交叉编译主机要做的工作与常规[非交叉]编译基本相同。
...高功率交叉编译主机通常比低功率主机快得多。
为什么?
编译器如何工作
据我记忆,2005 年在大学时,我被教导编译器会执行以下几个步骤:
- 预处理-压
#inclide
平等 - 令牌流解析 - 将源代码切割成单词和运算符流
- 语义解析 - 例如将变量名称连接在一起
- 翻译——将语义树转换为抽象程序
- 平铺 - 选择组合在一起的 CPU 操作来编写特定架构的抽象程序。
- 链接 - 程序单元通过修补的交叉引用内存地址链接在一起
特定于架构的优化可以通过几个步骤进行,但工作流程基本相同。
理解“平铺”很重要。抽象程序是程序的最原子形式,但通常不依赖于体系结构。 CPU 指令通常在一条指令中执行多项操作(即使在 RISC 指令集中)。 Tiling 选择组合在一起的架构指令来描述与抽象程序相同的程序。
不知何故,我总是想象像俄罗斯方块一样平铺
交叉编译器有何不同?
请记住,编译器本身就是一个被编译的程序。
交叉编译器的定义只是一种编译器,它本身使用与其平铺的指令集不同的指令集进行平铺。
因此,x86_64->ARM 交叉编译器运行的抽象程序与 ARM->ARM 编译器几乎完全相同!
- x86 主机编译 x86 程序与编译 ARM 程序之间的区别只是编译器在平铺时使用的指令集不同。
- x86主机编译ARM程序和ARM主机编译ARM程序的区别只是编译器的编译器使用了不同的指令集。
对于编译时间真正重要的是什么?
因此,重要的不是构建主机的架构,而是构建主机的原始 CPU 和内存能力。