通过生成 llvm IR,提高程序的执行性能
来源:互联网 发布:php运行环境配置 编辑:程序博客网 时间:2024/05/17 05:05
LLVM IR 简介
按照 LLVM 官网 的解释:
The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines, though it does provide helpful libraries that can be used to build them. The name “LLVM” itself is not an acronym; it is the full name of the project.
发展到现在 LLVM 已经不仅仅是一个编译器项目了,不过为了介绍 IR,我们不妨从编译器的角度来介绍一下 LLVM。编译器分为前端和后端,前端主要包括语法解析、语义分析以及生成抽象语法树,而后端则包括了汇编代码、目标文件的生成以及连接等等过程。LLVM 的目标是使前端和后端高度模块化,高度的每个模块都可重用,具体的做法就是通过 LLVM IR 连接前端和后端
LLVM IR 可以抽象的理解为 java 的字节码,后端理解成 jvm 的虚拟机,这样编译器开发人员就可以很方便的为某种语言开发一套编译器了:他只需要实现一个前端,用 LLVM IR 表示抽象语法树即可。而要添加对某个处理器平台的支持只需要添加对应平台的后端支持即可
为什么使用 LLVM IR
让我们来看一段伪代码:
for (int i = 0; i < num_fields_; ++ i) { switch (type_[i]) { case INTEGER: ProcessIntegerField(field_[i]); break; case STRING: ProcessStringField(field_[i]); break; ...... }}
类似这样的代码我们经常遇见,它有两个性能热点:1. for 循环的条件判断:i < num_field_s
;2. 循环体中的 switch case 表达式
而在运行时,num_fields_
以及 type_[i]
的值都是确定的,更准确的说:在执行上面那段代码钱,这两个值都是确定的,因此相比于上面的代码,下面的代码更加高效:
ProcessIntegerField(field_[0]);ProcessStringField(field_[1]);ProcessStringField(field_[2]);ProcessDoubleField(field_[3]);
上面的代码中,我们假设 num_fields_
的值为 4,type_[0]
到 type_[3]
的值分别为 INTEGER、STRING、STRING 以及 DOUBLE。这样的代码没有了分支判断,极大的增加了程序的执行性能
上面的例子告诉我们,在程序运行时,根据那些在函数运行前能确定的值,我们可以通过生成一个更加高效的、实现同样功能的函数来提高程序的执行效率,尤其是当那个函数被反复调用多次的时候,优化效果尤为明显
因为生成函数需要时间,实际上我们不一定非要选择 IR,完全可以选择其他语言,比如 C/Java/Python/PHP 等等。从生成函数到函数被编译成机器码也是一个时间开销,这个时间越短越好,而生成 IR 再利用 llvm 的 JIT 技术,这一时间被控制的非常非常短(随 IR 的大小而变化),因此 LLVM IR 成了不二的选择:利用 LLVM 提供的函数库在程序运行时根据已知的变量信息动态生成函数的 LLVM IR 代码,接下来利用 LLVM 的 JIT 库把 IR 代码转化为对应的机器码,并返回函数的指针,最后程序拿到函数指针调用生成的函数进行计算
如何编写 IR
先准备 LLVM 环境,你需要安装 llvm 和 clang,这里不对安装环境做过多描述
有两种方法编写 IR:一种是通过 LLVM 提供的 IRBuilder 来一条指令一条指令的生成 IR 代码;另一种是先用 C/C++ 写出需要生成 IR 代码的函数,然后用 clang 把 C/C++ 代码转化为 IR 代码
- 通过生成 llvm IR,提高程序的执行性能
- 基于LLVM IR的几款程序分析工…
- LLVM IR指令的抽象
- LLVM (4) 11.3 LLVM的代码表示:LLVM IR
- LLVM IR
- LLVM IR 语言的形式化描述
- LLVM IR 语法
- 一种基于LLVM IR的字符串变形方法
- LLVM IR is a compiler IR
- 【LLVM】《Getting Started with LLVM Core Libararies》读书笔记——IR和几个重要的类
- LLVM每日谈之二 LLVM IR
- LLVM教程( 三)-- LLVM IR
- 提高ABAP程序的性能
- (转)LLVM IR 简介
- LLVM IR 调试 常见错误
- llvm IR 语法小例子
- Python GIL 系列之通过设置进程运行的CPU来提高Python程序的性能
- javascript笔记:通过对作用域链和执行环境的深入理解所得出的提高javascript代码性能
- UNIX网络编程(一)-unp.h文件的编译
- 疯狂Java笔记:3.6 直接量
- E. Anton and Tree(缩点+树直径模板)
- uva 674 && hdu 2069 coin change(水完全背包)
- Oracle创建序列和触发器
- 通过生成 llvm IR,提高程序的执行性能
- Java NIO笔记之内存映射文件
- jprofiler 安装和连接linux(tomcat)
- jsp引用css和js文件方法 以及 java web应用程序文件结构
- 在(U)EFI环境下重装Grub2
- Minimum Absolute Difference in BST
- 疯狂Java笔记:3.7 运算符
- 向文档中添加列表项
- servlet相关配置及会话跟踪技术