当前位置: 首页 > news >正文

LLVM技术在GaussDB等数据库中的应用

目录

LLVM和数据库

LLVM适用场景

LLVM对所有类型的SQL都会有收益吗?

LLVM在OLTP中就一定没有收益吗?

GaussDB中的LLVM

1. LLVM在华为应用于数据库的时间线

2. GaussDB LLVM实现简析

3. GaussDB LLVM支持加速的场景

支持LLVM的表达式:

支持LLVM的算子:

4. GaussDB LLVM使用建议

GUC参数:

5. GaussDB LLVM性能表现

PostgreSQL中的LLVM

1. LLVM在PostgreSQL应用的时间线

2. PostgreSQL LLVM实现简析

3. PostgreSQL LLVM支持加速的场景

总结


万物互联的态势下,数据量的激增使得“如何提升数据处理性能”成为各家数据库共同面临的挑战。作为编译优化技术的代表,基于LLVM的CodeGen技术,能为每个查询生成定制的机器码替代原本的通用函数,减少实际查询时冗余的条件逻辑判断、虚函数调用并提高数据局域性,从而达到提升查询整体性能的目的,成为数据库性能优化的一项重要技术。

LLVM能在分析类场景中给用户带来较大的收益,也能在特定的交易性场景中给用户带来一定的收益。接下来详细解读一下LLVM技术在GaussDB等数据库中的应用吧。

LLVM和数据库

LLVM(Low Level Virtual Machine)是一款流行的开源编译器框架,是CodeGen(生成源代码的工具)技术的事实标准,被广泛运用于数据库(如KES, AnalyticDB, GaussDB)、大数据(如Spark)、AI平台(如tensorflow)等领域,用于提升数据处理的性能。

在没有引入LLVM这类CodeGen技术之前,数据库会使用通用的处理逻辑来处理数据。但通用逻辑“笨重”(递归、封装、类型判断转换)的代码实现方式,存在虚函数开销、缓存使用率低下、对指令集不敏感等性能短板。

引入LLVM之后,可以为具体的查询生成定制化的机器码,并尽可能地将数据存储在CPU的寄存器中进一步加快计算的速度:

  • LLVM天然支持JIT,该技术可以解决条件逻辑冗余的问题;

  • 减少大量的虚函数调用;

  • 将数据尽可能地从内存加载到Cache上;

  • LLVM做了很多自动矢量化的工作;

比如,下图左侧是通用代码,右侧是CodeGen之后的代码。CodeGen根据实际情况消除了不必要的循环和判断。

 图1 通用性处理逻辑和LLVM代码示意

另外,LLVM技术可以有不同的实现粒度。比如:可使用LLVM加速表达式计算,或再进一步,将多个算子融合编译成定制的机器码,或将自定义函数、存储过程等编译成定制的机器码。

 图2 LLVM的实现粒度

数据库在执行引擎中,运用LLVM技术提升SQL的执行速度。如下图所示:

图3  LLVM技术运用于执行引擎

LLVM适用场景

LLVM对所有类型的SQL都会有收益吗?

答案是否定的。

因为执行实时编译本身需要耗费一定的时间(简单表达式能做到毫秒级,复杂情况在百毫秒级),对于查询本身耗时较少的场景,加入LLVM反而会导致性能劣化。

因此,目前LLVM在OLAP/HTAP分析型业务场景中收益较大,有着广泛应用,而在OLTP交易型业务场景中,则相对没有那么广泛。

LLVM在OLTP中就一定没有收益吗?

答案同样是否定的。

找对场景,一样有收益。比如根据ISPRAS 2017年发表的实验结果(jit-compiling sql queries in postgresql using llvm)可知:pgbench测试下,OLTP场景中简单的查询加上JIT(Just-in-time及时编译,LLVM天然支持)扩展没有带来性能的提升,甚至将TPS(事务数/秒)从21.8降低到了7.8。

但是在Prepared query(plan cached)的情况下,和简单的查询相比,Plancache + CodeGen将TPS从21.8提升到了43,性能上有了约两倍的提升。

 

 图4 简单查询、CodeGen流程、Plancache和“Plancache +CodeGen”流程的性能对比

GaussDB中的LLVM

1. LLVM在华为应用于数据库的时间线

华为数据库在LLVM上的研究还是非常超前的。早在2015年,华为就作为PostgreSQL全球开发者大会的赞助商,在会上发表的动态编译(Go Faster with Native Compilation)演讲并引起了很大的反响。

当时社区领袖Josh Burkus在其博客里面,用一节篇幅专门详细介绍了华为动态编译的议题。

图5 2015年社区领袖Josh Burkus介绍华为的动态编译议题

2017年,华为在面向OLAP场景的数据库内核中突破了LLVM动态编译技术,并在运营商、金融证券等多个行业的POC项目中帮助客户提升数据处理性能,同时,在软件开发过程中充分模块化、通用化接口设计,将LLVM同年落地到面向OLTP的数据库设计中。

目前,GaussDB数据库对于LLVM也在不断地演进开发。

2. GaussDB LLVM实现简析

GaussDB针对列存(主要用于分析场景)、行存(主要用于交易场景)都实现了CodeGen。如下图所示,从代码模块层次来看:

1) GaussDB通过API接口层封装处理了LLVM环境、资源、基本元素等。

2) GaussDB在CodeGen层调用API接口进行了不同粒度的实现。

3) GaussDB在执行引擎侧根据情况使用CodeGen技术进行性能优化。

图6 GaussDB LLVM 模块层次图

GaussDB启动后会进行LLVM的初始化工作,检查CPU对CodeGen的支持情况,并进行环境初始化。

在执行启动阶段,以表达式为例,程序会判断当前表达式是否可JIT,是的话,则会进行IR函数的生成和生成定制机器码,及原本表达式执行函数的入口替代工作。

在实际执行过程中,运行处理函数(该函数已经在上一阶段进行了入口替代)进行实际执行工作。

在执行结束后的清理阶段,释放LLVM相关资源。

 图7 GaussDB CodeGen编译执行流程简图

GaussDB使用了阈值codegen_cost_threshold来估算当前查询使用LLVM技术是否能带来收益。如果处理数据的规模大于该阈值后,才会继续使用LLVM技术进行相关处理。该阈值代表行数,也可以理解成处理数据的规模,默认值为100000行,可以调节。

在OLAP场景中,GaussDB在判断是否能够对于一个算子进行CodeGen后(如:数据类型,算子类型判断等),开始生成对应的IR bytecode片段,之后MCJIT模块会调用生成的LLVM Module单元进行执行。

在OLTP场景中,GaussDB则会在Plan Cache场景下结合CodeGen框架,通过缓存机器码的方式,节省下编译生成中间语言IR Func以及优化成机器码的时间,整个过程是异步的。因此,在大量重复查询的场景下,后续的查询也会因为LLVM技术而受益。

另外,为了避免行数估计错误而选择CodeGen导致性能劣化,GaussDB还研发了当前业界独有的异步编译功能,即在查询语句确定要使用CodeGen的时候,将编译工作转交给后台线程,工作线程在JIT函数编译完成前继续使用原始执行逻辑执行,编译完成后,再替换成JIT函数执行。

3. GaussDB LLVM支持加速的场景

支持LLVM的表达式:

行存表达式计算支持的数据类型不受限制。

在向量化执行引擎中,仅当表达式出现在Scan节点的filter、Hash Join节点中的complicate hash condition, hash join filter, hash join target, Nested Loop节点中的filter, join filter, Merge Join节点的merge join filter, merge join target, Group节点中的filter表达式时,才会考虑是否使用LLVM动态编译优化。

在行执行引擎中,除一次性的表达式计算外,会考虑为所有算子的filter和Targetlist表达式都使用LLVM动态编译优化。

支持LLVM的算子:

Join :HashJoin(仅向量化执行引擎支持)

Agg :HashAgg

Sort(仅向量化执行引擎支持)

其中,HashJoin算子仅支持Hash Inner Join,对应的hash cond仅支持int4, bigint, bpchar类型的比较;HashAgg算子仅支持针对bigint, numeric类型的sum及avg操作,且group by语句仅支持int4, bigint, bpchar, text, varchar, timestamp类型操作,同时支持count(*)聚集操作。Sort算子仅支持对int4, bigint, numeric, bpchar, text, varchar数据类型的比较操作。除此之外,无法使用LLVM动态编译优化,具体可通过explain performance工具进行显示。

4. GaussDB LLVM使用建议

GUC参数:

enable_codegen:控制LLVM特性的打开和关闭。目前数据库内核侧默认打开。

codegen_cost_threshold:使用处理行数控制是否开启codegen,默认为10000。10000是通过实验验证得出的优化值,不建议将此值设置的过低。

另外,在开启LLVM特性的前提下,建议在允许的条件下尽可能设置较大的work_mem,如果出现大量下盘,则建议关闭LLVM动态编译优化。用户可通过analysis_options为on(LLVM_COMPILE),执行对应查询语句,在User Define Profiling中就可以看到LLVM的编译时间。结合此数据,可对codegen_cost_threshold进一步调整以获取更好的查询性能。

5. GaussDB LLVM性能表现

GaussDB实验室分别就codegen打开和关闭进行了TPCH性能测试。

表1 测试环境

测试结果显示,打开codegen时,带有qual的SQL,查询性能都有明显提升,且提升比例与qual在整个SQL中的占比相关,像Q6、Q12、Q19等qual占比较高的查询,性能提升也较多。

表2 TPCH 部分Query的测试结果

TPCC的性能提升并没有TPCH那么多,但据实验室数据,打开codegen后,tpmC提升了约7%。

PostgreSQL中的LLVM

1. LLVM在PostgreSQL应用的时间线

LLVM在PostgreSQL社区中的技术讨论开始的比较早:

2015年,上文提到的华为在PostgreSQL开发者大会上做的演讲;

2016年,PostgreSQL社区开始对JIT的实现进行了讨论;

2018年,PostgreSQL11中,第一次正式采用LLVM加速表达式计算。

2. PostgreSQL LLVM实现简析

如下图所示,和GaussDB相同,PostgreSQL执行引擎使用CodeGen技术做性能优化。针对表达式求值和元组分解为所需的属性集合两大性能瓶颈,做了可选的编译执行加速。

 图 8 PgSQL LLVM 模块层次图

PostgreSQL使用了三个参数来判断是否使用CodeGen优化:

jit_above_cost,表示超过多少cost 的查询才会使用JIT 功能。默认为100000,如果设置为-1 则关闭JIT。

jit_inline_above_cost,表示超过多少cost 的查询使用JIT 的inline 功能。默认为500000,-1则关闭inline 功能。

jit_optimize_above_cost,表示超过多少cost 的查询使用JIT 的optimization 功能。默认为500000,-1则关闭优化功能。

其中,后两个参数都需要设置得比jit_above_cost大,否则没有意义。这和GaussDB的使用数据集大小来控制是否开启CodeGen思想类似。

另外,PostgreSQL对于LLVM生成的字节码目前无法在plan cache中复用。这个功能的实现在PostgreSQL的中长期计划中。

3. PostgreSQL LLVM支持加速的场景

当前,PostgreSQL的JIT实现支持对表达式计算以及元组拆解的加速。

表达式计算被用来计算WHERE子句、target lists, aggregate聚合和projections投影。通过为每一种情况生成专门的代码来实现加速。

元组拆解是把一个磁盘上的元组转换成其在内存中表示的过程。通过创建一个专门针对该表布局和要被抽取的列数的函数来实现加速。

总结

华为和PostgreSQL关于LLVM特性的研究都起步很早,华为作为LLVM技术应用于数据库先驱者引领了PostgreSQL的技术发展。对于LLVM应用于数据库,GaussDB和PostgreSQL各有实现方法。GaussDB作为企业级数据库,对比PostgreSQL数据库,其实现特性多于PostgreSQL。

 欢迎小伙伴们交流~

相关文章:

LLVM技术在GaussDB等数据库中的应用

目录 LLVM和数据库 LLVM适用场景 LLVM对所有类型的SQL都会有收益吗? LLVM在OLTP中就一定没有收益吗? GaussDB中的LLVM 1. LLVM在华为应用于数据库的时间线 2. GaussDB LLVM实现简析 3. GaussDB LLVM支持加速的场景 支持LLVM的表达式&#xff1a…...

【SQL学习进阶】从入门到高级应用(三)

文章目录 ✨条件查询✨条件查询语法格式✨等于、不等于✨等于 ✨不等于 <> 或 ! ✨大于、大于等于、小于、小于等于✨大于 >✨大于等于 >✨小于 <✨小于等于 < ✨and✨or✨and和or的优先级问题✨between...and... &#x1f308;你好呀&#xff01;我是 山顶风…...

迷你手持小风扇哪个品牌续航强?五款强续航迷你手持小风扇推荐!

夏天就俩字儿&#xff1a;热和空调&#xff01;太阳大得让人想躲&#xff0c;一出汗&#xff0c;感觉全身毛孔都在喊“太热啦”&#xff01;这时空调简直是救命恩人啊&#xff0c;热得只想赖在屋里不出来。但出门总得面对大太阳&#xff0c;一出门就哗哗流汗。所以&#xff0c;…...

SpringBoot 微服务中怎么获取用户信息 token

SpringBoot 微服务中怎么获取用户信息 token 当我们写了一个A接口&#xff0c;这个接口需要调用B接口&#xff0c;但是B接口需要包含请求头内容&#xff0c;比如需要用户信息、用户id等内容&#xff0c;由于不在同一个线程中&#xff0c;使用ThreadLocal去获取数据是无法获取的…...

npm包-fflate

fflate 是一个快速、轻量级且纯JavaScript实现的压缩库&#xff0c;用于处理gzip、zlib和Deflate格式的数据压缩与解压缩。它专注于提供高性能的压缩算法实现&#xff0c;特别适合于浏览器环境及Node.js环境中使用&#xff0c;且不依赖任何外部库。fflate的优势在于其极小的体积…...

华为WLAN无线组网技术与解决方案

WLAN无线组网技术与解决方案 网络拓扑采用AP和AC旁挂式无线组网 配置思路&#xff1a; 1.让AP上线 1.1&#xff0c;使得AP能够获得IP地址 配置步骤&#xff1a; 1.把AC当作一个一个有管理功能的三层交换机 sys Enter system view, return user view with CtrlZ. [AC6605]vlan …...

闲鱼电商运营高级课程,一部手机学会闲鱼开店赚钱

课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/89360471 更多资源下载&#xff1a;关注我。 课程内容&#xff1a; 10-9、怎么寻找优质的货源店铺.mp4 11-10、怎么去选择商品图片.mp4 12-11、商品图片的注意避免事项.mp4 13-12、怎么写标题.mp4 …...

Yann LeCun 和 Elon Musk 就 AI 监管激烈交锋

&#x1f989; AI新闻 &#x1f680; Yann LeCun 和 Elon Musk 就 AI 监管激烈交锋 摘要&#xff1a;昨天&#xff0c;Yann LeCun 和Elon Musk 在社交媒体就人工智能的安全性和监管问题展开激烈辩论。LeCun 认为目前对 AI 的担忧和监管为时过早&#xff0c;主张开放和共享。而…...

C++重点基础知识汇总大全

文章目录 一些基础知识点指针和引用 一些基础知识点 1、十进制的数字比较长的时候&#xff0c;可以加方便阅读到底是几位&#xff0c;输出的时候跟不加是一样的效果 // 十进制可以加 cout << 13890324 << endl; // 13890324 // 二进制前加0b cout << 0b111…...

【Linux】线程安全及锁的使用

文章目录 前言一、锁1.定义一个锁变量2.pthread_mutex_init3.pthread_mutex_destroy4.pthread_mutex_lock/pthread_mutex_unlock5.静态变量锁和全局变量锁的初始化 二、问题描述及锁的运用三、RAII风格的锁 前言 临界资源: 在多个线程或进程间共享的资源. 临界区: 代码中访问临…...

深入解析绘图范式:面向对象与直接操作的较量

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 第一节&#xff1a;面向对象绘图的魅力 第二节&#xff1a;直接操作绘图模块的便捷性 第三…...

英特尔LLM技术挑战记录

英特尔技术介绍&#xff1a; Flash Attention Flash Attention 是一种高效的注意力机制实现&#xff0c;旨在优化大规模 Transformer 模型中的自注意力计算。在深度学习和自然语言处理领域&#xff0c;自注意力是 Transformer 架构的核心组件&#xff0c;用于模型中不同输入元…...

在 MFC 中 UNICODE 加 _T 与 L 长字符串,有什么区别?

在MFC&#xff08;Microsoft Foundation Classes&#xff09;和更广泛的Windows编程环境中&#xff0c;UNICODE宏用于指示程序应使用Unicode字符集&#xff08;通常是UTF-16&#xff09;来处理文本。当定义了UNICODE宏时&#xff0c;编译器和库函数会期待和处理宽字符&#xff…...

synopsys EDA 2016 合集 下载

包含如下安装包&#xff0c;如需安装服务也可联系我 FineSim_vL_2016.03 Laker201612 Library Compiler M-2016.12 Update Training PrimeTime M-2016.12 Update Training StarRC M-2016.12 Update Training SynopsysInstaller_v3.3 TSMC-65nm(OA) fm_vL-2016.03-SP1 fpga_vL-…...

CentOS 7如何使用systemctl管理应用

说明&#xff1a;本文介绍如何使用systemctl命令的方式来启动、查看、停止和重启应用&#xff0c;以安装后的prometheus、alertmanager为例&#xff1b; Step1&#xff1a;创建文件 在系统/etc/systemd/system/路径下&#xff0c;创建一个xxx.service文件&#xff0c;该文件内…...

武大深度学习期末复习-常见神经网络概念

深度学习经典神经网络概念、优缺点及应用场景 文章目录 一、多层感知机&#xff08;MLP&#xff09;1.1 结构和原理1.2 优缺点1.3 应用场景 二、卷积神经网络&#xff08;CNN&#xff09;2.1 结构和原理2.2 优缺点2.3 应用场景 三、循环神经网络&#xff08;RNN&#xff09;3.1…...

Leetcode3161. 物块放置查询(Go语言的红黑树 + 线段树)

题目截图 题目分析 每次1操作将会分裂成两块区间长度&#xff0c;以最近右端点记录左侧区间的长度即可 因此涉及到单点更新和区间查询 然后左右侧最近端点则使用redBlackTree&#xff0c;也就是python中的sortedlist ac code type seg []int// 把 i 处的值改成 val func (t …...

基于springboot实现医疗挂号管理系统项目【项目源码+论文说明】

基于springboot实现医疗挂号管理系统演示 摘要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&…...

ScrumMaster认证机构及CSM、PSM、RSM价值比较

企业现有的经营管理模式和传统的瀑布式交付模式&#xff0c;已经不能适应快速变化的市场响应和客户需求&#xff0c;现代的敏捷工作方式在过去数年涌现&#xff0c;比如Scrum&#xff0c;XP&#xff0c;看板&#xff0c;DevOps等敏捷方法&#xff0c;近十年Scrum在国内企业中备…...

加氢站压缩液驱比例泵放大器

加氢站压缩液驱液压系统的要求是实现换向和速度控制&#xff0c;对液压动力机构而言&#xff0c;按原理可区分为开式&#xff08;阀控&#xff09;- 节流控制系统和闭式&#xff08;泵控&#xff09;- 容积控制系统&#xff1a; 阀控系统 – 节流调速系统&#xff1a;由BEUEC比…...

MyBatis系统学习篇 - MyBatis逆向工程

MyBatis的逆向工程是指根据数据库表结构自动生成对应的Java实体类、Mapper接口和XML映射文件的过程。逆向工程可以帮助开发人员快速生成与数据库表对应的代码&#xff0c;减少手动编写重复代码的工作量。 我们在MyBatis中通过逆向工具来帮我简化繁琐的搭建框架&#xff0c;减少…...

SpringCloud的Config配置中心,为什么要分Server服务端和Client客户端?

SpringCloud的Config配置中心&#xff0c;为什么要分Server服务端和Client客户端&#xff1f; 在SpringCloud的Config配置中心中分了Server服务端和Client客户端&#xff0c;为什么需要这样分呢&#xff1f;它的思想是所有微服务的配置文件都放到git远程服务器上&#xff0c;让…...

「数据结构」队列

目录 队列的基本概念 队列的实现 头文件queue.h 实现函数接口 1.初始化和销毁 2.出队列和入队列 3.获取队头元素和队尾元素 4.队列长度判空 后记 前言 欢迎大家来到小鸥的博客~ 个人主页&#xff1a;海盗猫鸥 本篇专题&#xff1a;数据结构 多谢大家的支持啦&#xff…...

Python01 注释,关键字,变量,数据类型,格式化输出

# 导入模块 import keyword# 我的第一个Python程序 这是单行注释 快捷键&#xff1a;CTRL/这里是多行注释 可以写多行&#xff0c;用 三个单引号 包起来print(Hello work) print(你好&#xff0c;中国)aa 这是不是注释了&#xff0c;是多行文本。print(aa)# 快速创建 python …...

基于单片机智能防触电装置的研究与设计

摘 要 &#xff1a; 针对潮湿天气下配电线路附近易发生触电事故等问题 &#xff0c; 对单片机的控制算法进行了研究 &#xff0c; 设 计 了 一 种 基 于 单片机的野外智能防触电装置。 首先建立了该装置的整体结构框架 &#xff0c; 再分别进行硬件设计和软件流程分析 &#xf…...

机械行业工程设计资质乙级需要哪些人员

申请机械行业工程设计资质乙级需要的人员主要包括以下几个方面&#xff0c;具体要求和数量根据参考文章归纳如下&#xff1a; 一、主要专业技术人员 数量要求&#xff1a;主要专业技术人员数量应不少于所申请行业资质标准中主要专业技术人员配备表规定的人数。学历和职称要求…...

vivado改变波形图窗口颜色

点击右上角的设置图标 翻译对照...

蓝桥杯练习系统(算法训练)ALGO-932 低阶行列式计算

资源限制 内存限制&#xff1a;64.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 给出一个n阶行列式(1<n<9)&#xff0c;求出它的值。 输入格式 第一行给出两个正整数n,p&#xff1b;   接下来n行&…...

四川古力未来科技抖音小店安全靠谱,购物新体验

在数字化浪潮席卷而来的今天&#xff0c;电商行业蓬勃发展&#xff0c;各种线上购物平台如雨后春笋般涌现。其中&#xff0c;抖音小店凭借其独特的短视频直播购物模式&#xff0c;迅速赢得了广大消费者的青睐。而四川古力未来科技抖音小店&#xff0c;更是以其安全靠谱、品质保…...

深入理解Seata:分布式事务的解决方案

在现代的微服务架构中&#xff0c;随着业务系统的不断拆分和模块化&#xff0c;分布式事务成为一个重要的挑战。为了解决微服务架构下的分布式事务问题&#xff0c;Seata应运而生。Seata&#xff08;Simple Extensible Autonomous Transaction Architecture&#xff09;是一款开…...