编译器基础概念
文章目录
- 编译器与解释器
- 解释器 vs 编译器对比
- 编译方式
- Just-In-Time (JIT) 编译
- Ahead-Of-Time (AOT) 编译
- JIT(即时编译)与 AOT(提前编译)对比
- 什么时候用到JIT什么时候用到AOT?
- Pass 和 IR
- Pass
- 传统编译器
- 编译器的发展历史(History of Compiler)
- GCC 编译过程与原理(GCC Process and Principle)
- LLVM/Clang 编译过程与原理(LLVM/Clang Process and Principle)
- AI 编译器
- AI 编译器的发展历史(History of AI Compiler)
- AI 编译器的通用架构(Base Common Architecture)
- 参考
编译器与解释器
解释器 vs 编译器对比
特性 | 解释器 (Interpreter) | 编译器 (Compiler) |
---|---|---|
输入处理 | 每次读取一行 | 整个程序一次性处理 |
输出 | 不生成中间代码 | 生成中间目标代码(如 .obj 或 .class ) |
工作机制 | 编译和执行同时进行 | 先完成全部编译,再执行 |
存储 | 不保存机器代码 | 存储编译后的机器代码(如 .exe ) |
执行方式 | 解释过程即执行,逐行运行 | 执行与编译分离,运行编译后的独立程序 |
程序生成 | 无输出程序,每次执行需重新解释源码 | 生成可独立运行的程序(如 .exe ) |
代码修改 | 直接修改源码即可运行 | 需重新编译修改后的源码 |
运行速度 | 慢(逐行解释) | 快(直接执行机器码) |
内存占用 | 较少(无中间代码) | 较多(需存储目标代码) |
错误处理 | 逐行显示错误,需纠正后继续解释下一行 | 编译时显示所有错误,必须修正才能生成可执行程序 |
错误监测 | 容易(实时反馈) | 需完整编译后反馈 |
适用语言 | PHP、Perl、Python、Ruby | C、C++、C#、Scala、Java |
典型步骤 | 1. 创建代码 2. 直接解释执行 | 1. 创建代码 2. 语法分析 3. 生成机器码 4. 链接运行 |
编译方式
程序主要有两种运行方式:
- 静态编译:程序在执行前全部被编译为机器码,称为AOT(Aheadof time),即“提前编译"
- 动态解释:程序边编译边运行,通常将这种类型称为 JIT(Just in time)即“即时编译";
Just-In-Time (JIT) 编译
- 运行时将代码编译为机器码,适用于动态语言,具有更高的运行时优化能力。
Ahead-Of-Time (AOT) 编译
- 在程序运行前将代码编译为目标机器码,启动速度快,适合静态语言。
JIT(即时编译)与 AOT(提前编译)对比
特性 | JIT(Just in Time)即时编译 | AOT(Ahead of Time)提前编译 |
---|---|---|
优点 | ||
硬件适配优化 | ✅ 根据当前硬件实时生成最优机器指令 | ❌ 无法针对运行环境动态优化 |
运行时优化 | ✅ 根据程序实际运行情况优化指令序列 | ❌ 静态优化,无法利用运行时信息 |
动态链接支持 | ✅ 唯一支持动态链接的方案 | ❌ 无法支持动态链接 |
内存利用率 | ✅ 可基于进程内存实际情况调整代码 | ❌ 内存分配固定 |
缺点 | ||
运行时性能消耗 | ❌ 编译占用运行时间,可能导致卡顿 | ✅ 无运行时编译开销 |
优化限制 | ❌ 需权衡编译时间和优化程度 | ✅ 可进行充分静态优化 |
启动性能 | ❌ 初始编译无法立即达到最高性能 | ✅ 启动即达峰值性能 |
程序启动速度 | ❌ 初始编译影响启动速度 | ✅ 显著加快程序启动 |
安装/部署影响 | ✅ 无额外安装时间 | ❌ 增加程序安装时间 |
语言一致性 | ✅ 保持高级语言特性 | ❌ 可能牺牲语言一致性 |
存储占用 | ✅ 不保存编译结果 | ❌ 预编译内容占用额外存储空间 |
典型应用场景 | Java/JVM、JavaScript引擎、动态语言环境 | C/C++程序、系统级开发、移动端应用 |
什么时候用到JIT什么时候用到AOT?
选 JIT 当:
- 需要动态优化、跨平台或快速开发迭代。
- 允许牺牲部分启动时间换取长期性能(如服务端应用)。
选 AOT 当:
- 要求快速启动、资源受限或需静态分发(如移动端 APP)。
- 代码稳定且无需运行时调整(如系统级软件)。
Pass 和 IR
- Pass:编译器的一个处理阶段,用于分析和优化程序。
- IR(Intermediate Representation):中间表示,是源代码与目标代码之间的抽象形式,方便分析与优化。
Pass
传统编译器
编译器的发展历史(History of Compiler)
- 早期编译器将高级语言翻译成机器代码
- 随着程序复杂度增加,出现多阶段、可优化的编译器设计
GCC 编译过程与原理(GCC Process and Principle)
- 预处理(Preprocessing)
- 编译(Compilation)
- 汇编(Assembly)
- 链接(Linking)
- 支持多平台和多种优化选项
LLVM/Clang 编译过程与原理(LLVM/Clang Process and Principle)
- 模块化设计,前端(Clang)、中端(LLVM IR)、后端(目标代码生成)分离
- 易于扩展和优化
- 广泛用于研究与工业界
AI 编译器
AI 编译器的发展历史(History of AI Compiler)
- 初期尝试使用启发式方法优化编译过程
- 随着机器学习的发展,逐渐应用神经网络和强化学习进行自动优化
AI 编译器的通用架构(Base Common Architecture)
- 前端:将源代码转为 IR
- IR 优化器:使用 AI 方法预测最优优化策略
- 后端生成器:将优化后的 IR 转为机器码
- 反馈环节:通过运行数据训练模型,持续优化编译效果
参考
- 编译器和解释器啥区别?AOT和JIT啥区别?Pass和IR又是什么?【AI编译器】系列01篇
- 编译器基础介绍