【连载】如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(2)

前文回顾:

  1. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1)

  2. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2)

  3. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(3

  4. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(4)

  5. 如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1)

9b3dc83c7fff74cd77a5ec2edb9fa899.png

目录

  • openGauss数据库SQL引擎

  • openGauss数据库执行器技术

    一.openGauss数据库执行器概述

    二.openGauss执行引擎

三.高级特性介绍

Ⅰ.编译执行

Ⅱ.向量化引擎

  • openGauss存储技术

  • openGauss事务机制

  • openGauss数据库安全

3efdda7d9341908b1921d8397507d4b3.png

openGauss数据库执行器技术

三.高级特性介绍

这个章节我们介绍下openGauss执行器里面几个高级特性,在介绍特性之前,先简单介绍下当前CPU体系架构里影响性能的几个关键因素,这些关键因素和其应对的技术构成了执行器里两个关键技术,编译执行和向量化引擎。

§ 函数调用:函数调用过程中需要维护参数和返回地址在栈帧的管理,处理完成之后还要调回到之前的栈帧,因此在用户的函数调用过程中,CPU要消耗额外的指令来进行函数调用上下文的维护。

§ 分支预测:指令在现代CPU中以流水线运行,当处理器遇到分支条件跳转时,通常不能确定执行那个分支,因此处理器采用分支预测来预测每条跳转指令是否会执行。如果猜测准确,那么流水线中就会充满指令,如果对跳转猜测错误,那么就要要求处理器丢掉它这个跳转指令后的所有已做的操作,然后再开始用从正确位置处起始的指令去填充流水线,可以看到这种预测错误会导致很严重的性能惩罚,会导致大约20-40个时钟周期的浪费,从而导致性能的严重下降。这里可以看到提速方式一共有两种。是更准确的智能预测,但是无论多么准确,总会存在误判,另外一种就是从根本上消除分支。

§ CPU存取数据:CPU对于数据的存取存在鲜明的层次关系,在寄存器、CPU 高速缓存(CACHE)、内存的存取速度越来越慢,所承载的容量越来越大。同时CPU在访问数据的时候也会遵循从快到慢的原则,比如CACHE中找不到的数据才会从内存中找,而这两者的访问速度差距在两个数量级。如果CPU的访问模式是线性的(比如访问数组),CPU会主动将后续的内存地址预加载到CACHE,这就是CPU的数据预取。因此程序如果能够充分利用到这个特征,将大大提速程序的性能。

§ SIMD:单指令多数据流,对于计算密集型程序来说,可能经常会需要对大量不同的数据进行同样的运算。SIMD引入之前,执行流程为同样的指令重复执行,每次取一条数据进行运算。而SIMD可以一条指令执行多个位宽数据的计算。比如当前最新的体系结构已经支持512位宽的SIMD指令,那么对于16位整型的加法,可以并行执行32个整型对的加法。

Ⅰ.编译执行

在上一篇文章【如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1)】的表达式计算小节中,介绍了基于遍历树的表达式计算框架,这种框架的好处是清晰明了,但是在性能上却不是最优,主要有以下几个原因:

§ 表达式计算其框架的通用性决定了其执行模式要适配各种不同的操作符和数据类型,因此在运行时要根据其表达式遍历的具体结果来确定其执行的函数和类型,对这些类型的判断要引入非常多的分支判断。

§ 表达式计算在整体的执行过程中要进行多次的函数调用,其调用的深度取决于其树的深度,这一部分也有着非常大的开销。

这两个核心原因,分支判断和函数调用同样在执行算子中也是影响性能的关键因素,为了提升其执行速度,openGauss引入了业界著名的开源编译框架LLVM(Low Level Virtual Machine)来提速的执行速度,LLVM是一个通用的编译框架,能够支持不同的计算平台。

LLVM提升整体表达式计算的核心要点如下:

1) openGauss内置的LLVM编译框架通过为每一个计算单元(表达式或者执行算子里面的热点函数)生成一段独特的执行代码,由于在编译的时候提前知道了表达式涉及的操作和数据类型,为这个表达式生成的执行代码将所有的逻辑内联,完全去除函数调用。

比如对于上一篇文章【如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1)】中提到的表达式计算过程,openGauss内置的LLVM编译为这个表达式生成了下面这样一段特殊代码。这里面已经没有任何其他的函数调用,所有的函数都已经被内联在一起,同时去掉了关于数据类型的分支判断。

Bool qual()
{
bool qual1res = 2 * w_tax + 0.9 > 1;
bool qual2res = w_city !=’Beijing’;
Return qual1res && qual2res;
}

2) LLVM编译框架利用编译技术最大程度的让生成的代码将中间结果的数据存储在CPU寄存器里,让数据读取的速度加快。

Ⅱ.向量化引擎

在【如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1)】的概要介绍中提到了执行器的数据流动模式:控制流向下、数据流向上。传统的执行引擎数据流遵循一次一元组的传输模式,而向量化引擎将这个模型改成一次一批元组的模式,这种看似简单的修改却带来巨大的性能提升,如图6所示。

b66d86104bd13a506d3ed1c3b3006618.png

图6  单个元组与向量化元组对比

其中的主要提升原因可以应对上面介绍的CPU架构里影响性能的几个关键因素。

§ 一次一元组的函数模型在控制流的调动下,每次都需要进行函数调用,调用次数随着数据增长而增长,而一批元组的模式则大大降低了执行节点的函数调用开销,如果我们设定一次一批的数量为1000,函数调用相对于一次一元组能减少三个数量级。

§ 一次一批元组的模式在内部实现通过数组来表达,数组对于CPU的预取非常友好,能够让数组在后续的数据处理过程中,大概率能够在CACHE中命中。

比如对于下面这个简单计算两个整形加法的表达式函数(其代码仅为了展示,不代表真实实现),下面展示了一次一元组和一次一批元组的两种写法:

一次一元组的整形加法:

int int4addint4(int4 a, int b)
{
     Return a+b;
}

一次一批元组的整形加法:

void int4addint4(int4 a[], int b[], int res[])
{   for(int i = 0; i < N; i++)
       res[i] = a[i] + b[i];
}

一次一批元组的这个计算函数,因为CPU CACHE的局部性原理,数据和指令的cache命中率会非常好,极大提升处理性能。

§ 一次一批元组的数据数组化的组织方式为利用SIMD特性带来了非常好的机会,SIMD能够大大提升在元组上的计算性能,还是以刚才上述整形加法的例子,我们可以重写上述的函数如下。可以看到,由于SIMD可以一次处理一批数据,循环的次数衰减,性能能得到进一步提升。

void int4addint4SIMD(int4 a[], int b[], int res[])
{  
for(int i = 0; i < N/SIMDLEN; i++)
   res[i..i+SIMDLEN] = SIMDADD(a[i..i+SIMDLEN], b[i..i+ SIMDLEN];
}

至此,openGauss数据库执行器技术章节结束,下一章将开启openGauss存储技术的学习,未完待续......

若您对本系列文章感兴趣,敬请关注我们的公众号,我们将在每周二、周四进行更新。

更多数据库行业相关内容,欢迎光临 2021 数据技术嘉年华 :https://www.modb.pro/dtc2021(扫描下方二维码免费领取大会门票)

END

推荐阅读:267页!2020年度数据库技术年刊

推荐下载:2020数据技术嘉年华PPT下载


2020数据技术嘉年华近50个PPT下载、视频回放已上传墨天轮平台,可在“数据和云”公众号回复关键词“2020DTC”获得!

你知道吗?我们的视频号里已经发布了很多精彩的内容,快去看看吧!↓↓↓

点击下图查看更多 ↓

64dfed5f26edb542df0cf0a276f65a42.png

71f679c463e7dded3e81cffac09e7d2e.png

a32ecda402cdeb7e318af373fc16bc05.png

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看” 

你的喜欢会被看到❤

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值