Impala中的代码生成技术
Cloudera Impala是一种为Hadoop生态系统打造的开源MPP(massive parallel processing)数据库,它主要为分析型查询负载而设计,而非OLTP。Impala能最大限度地利用现代硬件和高效查询执行的最新技术。LLVM下的运行时代码生成就是用来提升执行性能的技术之一。
LLVM简介
LLVM是一个编译器及相关工具的库(toolchain),它不同于独立应用式(stand-alone)的传统编译器,LLVM是模块化且可重用的。它允许Impala这样的应用在运行的进程内执行JIT(just-in-time)编译。尽管LLVM因一些特殊的能力以及著名的工具,如比GCC更优的Clang编译器,但真正使LLVM区别于其他编译器的是它的内部架构。
经典静态编译器(像多数C编译器)中,最流行的设计是前端、优化器、后端组成的三阶段设计。前端解析源码并生成抽象语法树(AST,Abstract Syntax Tree)。优化器会做很多优化来提升代码性能。后端(或称代码生成器)将代码转换成目标平台的指令集。这种模型对解释器、JIT编译器。JVM也是这种模型的一种实现,它使用字节码作为前端和优化器之间的接口。
这种经典设计对于多语言(包括源语言和目标语言)支持非常重要。只要优化器内部使用一种公共代码表示,前端和后端就能够编译任意的语言。当需要移植(porting)编译器来支持一种新语言时,只需实现一个新前端,而优化器和后端都可以重用。否则就要重新实现整个编译器,支持M种源语言*N种目标语言。
尽管各种编译器教科书中都讲到三阶段设计的种种优点,但实际上它从未被实现过。像Perl、Python、Ruby和Java的编译器实现并没有共享任何代码。此外,还有各种各样的特殊用途的编译器,例如图像处理、正则表达式等CPU密集型的子领域的JIT编译器。GCC由于混乱的代码结构而无法提取出可重用的组件,例如前端和后端重用了某些全局变量等,所以我们无法将GCC嵌入到应用程序中。下图是LLVM对三阶段设计的实现。
Impala中的LLVM
Impala使用LLVM在运行时产生完全优化并且查询特定的函数,这比通用的预编译函数有更好的性能。中的代码示例。编译时记录个数和类型都是未知的,所以中的数组offsets_和types_在每次查询开始时创建而不会改变,于是在代码生成的函数版本中,展开for循环后,这些数组中的值可以直接内联化。
Ø 内联虚函数调用:虚函数对性能的影响很大,尤其是函数很小很简单,因为它无法内联化。因此当对象实例的类型在运行时可知时,我们可以使用代码生成来取代虚函数的调用,并做内联化。这对于表达式树的求值尤为有价值。在Impala中,表达式由操作和函数的树组成,例如下图2。树中出现的每种表达式都是覆盖(override)表达式基类的函数来实现的,基类会递归地调用各个子表达式。许多表达式函数都是非常简单的,例如两数相加,于是虚函数调用的开销甚至大过表达式求值的开销。通过代码生成移除虚函数并内联化,表达式可以无需函数调用而直接求值。此外,内联后的函数使编译器做进一步的优化,例如子表达式消除等。
用LLVM生成代码
当Impala受到查询计划(query plan,由Impala的Java前端负责生成)时,LLVM会被用来在查询执行开始前,生成并编译对性能至关重要的函数的查询特定版本。LLVM主要使用IR(intermediate representation)来生成代码,例如LLVM的前端Clang C++编译器生成IR,LLVM优化IR并将其编译成机器码。IR类似于汇编语言,由一些简单的、能够直接映射成机器码的指令组成。在Impala中有两种技术来生成IR函数:使用LLVM的IRBuilder API来编程式地生成IR指令;使用CLang将C++函数交叉编译成IR。
下图是IR的例子。可以看出,IR是一种类RISC的虚拟指令集。它支持加减、比较、分支等指令。此外,IR还支持标签。但与多数RISC不同的是:
Ø LLVM是强类型的,它有一套简单的类型系统,例如i32, i32**,add i32。
Ø LLVM IR支持无限的临时寄存器,以%开头。
因为优化器不受源语言和目标平台限制,所以IR的设计也要遵守这个原则。
在LLVM中,优化器被组织成优化pass的管道,常见的pass有内联化、表达式重组、循环不变量移动等。每个pass都作为继承Pass类的C++类,并定义在一个私有的匿名namespace中,同时提供一个让外界获得到pass的函数。
我们可以决定pass的执行顺序甚至是否执行。当我们实现一种图像处理语言的JIT编译器时,我们可以去掉没用的pass。例如,如果通常都是大函数的话,就没必要浪费时间内联。如果指针很少的话,那么别名分析和内存优化就变得可有可无。但是LLVM不是万能的,PassManager本身也并不知道每个pass内部的逻辑,所以这还是由我们实现者来确定的。
参考资料
1 Runtime Code Generation in Cloudera Impala
2 The Architecture of Open Source Application
http://www.aosabook.org/en/llvm.html
Impala中的代码生成技术的更多相关文章
- 基于 Eclipse 平台的代码生成技术
------------------------------------------------------------------ 转自http://www.ibm.com/developerwor ...
- tp中使用分页技术
1 public function showList() { $m_ld = D ( 'guangxi_ld' ); $page = I ( 'get.p', 1 ); // 在配置中获取分页值 $p ...
- Web 开发中应用 HTML5 技术的10个实例教程
HTML5 作为下一代网站开发技术,无论你是一个 Web 开发人员或者想探索新的平台的游戏开发者,都值得去研究.借助尖端功能,技术和 API,HTML5 允许你创建响应性.创新性.互动性以及令人惊叹的 ...
- 【python游戏编程之旅】第七篇---pygame中的冲突检测技术
本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 上一个博客我们一起学习了pygame中的Sprite模块和如何加载动画:http://www.cnblogs ...
- .net中对象序列化技术浅谈
.net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...
- SpreadJS 中应用 KnockoutJS 技术
SpreadJS 支持 Knockout (KO)技术, KnockoutJS 是一个使用 MVVM 模式的 JavaScript 库,允许双向数据绑定,使数据和UI界面进行实时的交互更新.关于KO的 ...
- Unity教程之再谈Unity中的优化技术
这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体 这一步主要是为了针对性能瓶颈中的”顶点 ...
- GPRS GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术
GPRS 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可 ...
- Android中直播视频技术探究之---基础知识大纲介绍
一.前言 最近各种视频直播app到处都是,各种霸屏,当然我们也是需要体验的,关于视频直播的软件这里就不介绍了,在不是技术的人来看,直播是一种潮流,是一种娱乐方式,但是作为一个高技术的,我们除了看看,更 ...
随机推荐
- ●BZOJ 4237 稻草人
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4237 题解: CDQ分治,单调栈 把所有点先按x从小到大排序,然后去CDQ分治y坐标. 在分 ...
- 2015 多校联赛 ——HDU5371(manacher + 枚举)
Sample Input 1 10 2 3 4 4 3 2 2 3 4 4 Sample Output Case #1: 9 要求找出一段数字. 将其分成3部分,第①和第②部分成回文字串,第②和第 ...
- ●BZOJ 4665 小w的喜糖
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4665 题解: 容斥,dp令 v[i] 表示原来拥有i类糖果的人数. (一个套路,首先把每个糖 ...
- hdu 5475(线段树)
题意: 两个操作:① 当为1时 ,乘上后面的数 ② 当为2时,除以第x次乘的数 还说了2操作后面的n不会重复(就这明显看出线段树- -,然而并没有看出来,还是靠的队友) 1则对每个节点赋值,2则将相应 ...
- C++ C# python 中输入输出函数对比
C++ cin>>"nihao";cout<<"nihao"<<endl; C# System.Console.ReadLi ...
- C语言第五次作业——循环结构
C语言程序设计第五次作业--循环结构(1) (一)改错题 输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增 ...
- 一个使用 Python 的人工智能聊天机器人框架
一个Python 的 AI Chatbot框架 建立一个聊天室可以听起来很棒,但它是完全可行的. IKY是一个内置于Python中的AI动力对话对话界面. 使用IKY,很容易创建自然语言会话场景,无需 ...
- java Session统计在线用户,并且显示在线用户
关键字: httpsession 1.http://www.jspcn.net/htmlnews/11049329478121583.html 监听器 2.session.invalida ...
- python文件转exe
.py文件转exe文件 1.软件说明: 用python写一个视频处理软件,用到的库是moviepy 2.所用软件: Python 3.6.5 32位 pycharm 专门的python编辑ide,推 ...
- web领域的实时推送技术-WebSocket
WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex),即是所谓的及时推送技术. 在此之前,很多网站为了实现及时推送技术通常采用的是 ...