前文回顾:

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

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

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

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

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

目录

  • openGauss数据库SQL引擎

  • openGauss数据库执行器技术

    一.openGauss数据库执行器概述

    二.openGauss执行引擎

三.高级特性介绍

Ⅰ.编译执行

Ⅱ.向量化引擎

  • openGauss存储技术

  • openGauss事务机制

  • openGauss数据库安全

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所示。

图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”获得!

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

点击下图查看更多 ↓

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

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

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

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

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

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

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

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

  3. 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(4)

    点击蓝字 · 关注我们 前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握 ...

  4. 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(3)

    点击蓝字 · 关注我们 前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握 ...

  5. 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(2)

    点击蓝字 · 关注我们 前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握 ...

  6. 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(1)

    点击蓝字 关注我们 前文回顾: 1.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1) 2.如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2) 3.如何掌握op ...

  7. 【连载】如何掌握openGauss数据库核心技术?秘诀四:拿捏事务机制(4)

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

  8. 【连载】如何掌握openGauss数据库核心技术?秘诀四:拿捏事务机制(3)

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

  9. 【连载】如何掌握openGauss数据库核心技术?秘诀四:拿捏事务机制(2)

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

最新文章

  1. LeetCode简单题之丢失的数字
  2. 1129 Recommendation System (25 分)【难度: 一般 / 知识点: 滑动窗口】
  3. linux下挂接fat32分区
  4. JAVA基础学习大全(笔记)
  5. 10034 - Freckles 克鲁斯克尔最小生成树!~
  6. 二、Zabbix-zabbix server部署-LNMP
  7. 程序设计基础(C语言)课程设计报告,C语言程序设计基础课程设计报告.doc
  8. Python 命令行之旅:使用 argparse 实现 git 命令
  9. 综合云平台 - 架构 - 01
  10. 【Hill Cipher】希尔密码描述 by Xiaosi_lemon
  11. 业务方如何理解产品,更顺利地推进产品需求?
  12. VBR与CBR的区别是什么?
  13. 操作系统核心与驱动程序
  14. 小程序调用服务器图片错误,微信小程序列表图片加载错误处理
  15. bagging通过bootstrap构建集成分类器
  16. 香港科大研发出Germagic杀菌涂层,可杀灭新冠病毒
  17. 静态HTML网页设计作品 DIV布局家乡介绍网页模板代码---(太原 10页带本地存储登录注册 js表单校验)
  18. 275.算法设计工具―STL
  19. 读《筚路蓝缕——世纪工程决策建设记述》II
  20. leetcode 1641. Count Sorted Vowel Strings(python)

热门文章

  1. 计算机硬件的五大单元
  2. 克服协作的五种障碍_如何克服社区管理的障碍
  3. 视频 人员统计 开源_开源人员的独特之处
  4. android12适配机型,OPPO率先适配安卓12版本
  5. 求两个链表的第一个公共结点各种情况及三种思路分析
  6. ROS笔记(39) 串口配置
  7. 视觉SLAM笔记(31) 特征提取和匹配
  8. windows防火墙ntp服务器_NTP教学续集已发送,请你查收!
  9. 计算机的应用可以分为几类,计算机分为哪几类专业
  10. 您已到达6300千米深度,速度8 公里/秒,正在穿过地心 [置顶]