前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Codegen技术学习

Codegen技术学习

作者头像
大数据和云计算技术
发布2018-03-08 13:18:06
2.6K0
发布2018-03-08 13:18:06
举报

Codegen在spark中的应用

除了前面查询优化中讲到逻辑优化器之外,Spark在1.5版本中引入了比较大的一个动作就是DataFrame执行后端的优化,引入了codegen技术。(Tungsten项目的一部分)

从上图中可以看除,spark通过Codegen在运行前将逻辑计划生成对应的机器执行代码,由Tungsten backend执行。

原理

从上图中可以看除,spark通过Codegen在运行前将逻辑计划生成对应的机器执行代码,由Tungsten backend执行。

以spark为代表的基于内存的计算引擎,使得I/O性能比传统基于硬盘有10倍左右的性能提升,但与之同时,CPU的瓶颈会更明显,以传统Postgres的引擎为例,操作数据都被缓存到内存的Page Cache上面,它做最简单的Count(*)统计都只能勉强达到每秒钟400万行左右,而真实所需要的操作其实是很少的,按照2010年的X86 CPU而言,其实处理这些计算是非常简单的,但实际性能还是很低,为什么呢?先看看现在X86 CPU性能特征,随着技术本身的发展,X86 CPU本身的处理能力非常强大,但是一切换Context就会出现性能方面的小滑坡。如果等待处理的命令和数据没有被预缓存在Cache上面,而是需要访问的内存的话,会有一个更大的性能滑坡。既然大家都了解CPU本身的瓶颈,下面来聊聊传统数据库处理引引擎的短板有哪些?主要有以下四点:

其一是条件逻辑冗余,数据处理引擎代码非常繁琐,因为SQL语句本身非常复杂,所以数据引擎为了支持那些复杂的SQL语句,使得数据处理引擎需要复杂的条件逻辑来处理,甚至一个Switch循环里面会有成百上千的case这样的选择逻辑,虽然Switch循环本身会被编译器进行一定程度的优化,但是最终机器码中的分支指令会一定程度上阻止指令的管道化(instruction pipelining)和并行执行(instruction-levelparallelism)。

其二是虚函数的调用,和第一个问题的原因类似,因为数据处理引擎要支持极为复杂的SQL语句,还有十几种的数据类型,比如,程序在处理add这个逻辑的时候,此时数据处理引擎需要根据来源数据是INT还是BIGINT来选择不同的函数来处理,所以在实际处理时,肯定只能用虚函数来转给具体的执行函数,这个对CPU的影响肯定是非常明显的,因为很多时候虚函数调用本身的运行成本,比这个函数本身执行成本更高。更因为如此,内联函数这个最常见的性能优化方式也无法被使用。

其三是需要不断地从内存中调用数据,而无法一次性将数据从内存加载至Cache上,比如,常见的For循环,虽然知道下一个数据就在下一个偏移地址,但还是要从内存上面读取,这样读取开销很大而且阻止整个CPU管道化的操作。

其四是因为不同x86CPU年代不同,所以支持不同扩展指令集,而这些新的指令集对很多操作都能提升100%以上的性能,比如,有些比较新的CPU支持SSE 4.2,而有些却不支持,为了保证数据引擎能跨不同的硬件平台,所以数据引擎很少支持一些扩展的指令集,这导致浪费了本来可以提升的性能没有得到支持。

为了接上述瓶颈,Google研发的Tenzing技术里面提出基于LLVM编译框架实现动态生成代码Codegen这个技术,并且通过这个技术基于MapReduce分布式框架下面的类SQL系统的性能也能接近商业收费并行数据库的水准。Codegen这种方式,就是在SQL执行前才编译具体的执行代码。那么使用Codegen的好处如下:

其一是简化了条件分支,因为在生成代码的时候,程序已经获知运行时的信息,通过展开for循环(因为我们已经知道循环次数)和解析数据类型,所以可以将if/switch这些分支指令这样的语句就能优化掉,这是非常简单有效的。

其二是内存加载,我们可以使用代码生成来替代数据加载,这样极大减少内存的读取,增加CPU Cache的利用率,这对CPU性能而言非常有帮助。

其三是内联虚函数的调用,因此当对象实例的类型在运行时可知,可以使用代码生成来取代虚函数的调用,并做内联化,这样表达式可以无需函数调用而直接求值。此外,内联后的函数使编译器做进一步的优化,例如子表达式消除等。

其四是能利用最新的指令集,在Codegen的时候,由于Codegen本身是在即将执行的那个节点执行,所以它很方便就能感知到其底层CPU到底支持那个版本最新的指令集,比如是SSE 4.2还是SSE4.1,所以Codegen完全会根据具体的指令集支持来编译具体的执行代码,使其能尽可能地利用最新的指令集。

应用场景

Codegen技术使解析语言的性能接近预编译语言,而且兼容多种语言。可以看出来服务器端编程未来语言会越来越不重要,表达力越强,越容易使用的语言越受欢迎。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据和云计算技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Codegen在spark中的应用
  • 原理
  • 应用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档