数据分析和应用的重要性日益增长,对于数据平台和数据计算系统来说,极致的性能是关键需求之一。为实现更高效的数据并行计算,一款优秀的执行器需要能够充分利用硬件资源,如 CPU 的并行计算能力和 SIMD 指令集。此外,优化数据的存储和读取方式、合理的任务调度和资源管理,以及持续优化和改进都是确保性能的关键因素。
PieCloudDB 为了助力企业建立以数据资产为核心的竞争壁垒,为客户提供卓越性能和高效的数据处理能力,颠覆原有执行器设计,自研了高效的全新向量化执行器。向量化计算技术的引入使得 PieCloudDB Database 能够充分利用现代处理器的并行计算能力,实现数据的快速并行处理。
向量化计算是一种计算机处理器或计算引擎的设计方法,利用 SIMD 指令集来操作向量数据。它可以在单个指令的控制下对一组数据进行并行计算,提高计算效率和性能。
现代 CPU 中所支持的专用 SIMD 寄存器和硬件单元为向量化操作提供了强大的支持,让使用 SIMD 指令集进行并行计算更加高效,并且能够充分利用 CPU 的计算能力。接下来,我们来详细介绍一下 CPU 的体系结构帮助大家理解。
现在冯诺依曼计算机模型一般有 5 个核心组件:运算、存储、控制、输入以及输出。CPU 执行过程中一般会涉及取指令、解码、执行、回写这几个最基础的阶段,为了提高 CPU 的性能,现代 CPU 一般是引入了多级流水线、乱序执行等技术来提升性能。比如 5 级流水线,就是在同一个 CPU Cycle 内,可以处理 5 个不同的操作。
TMAM(自顶向下的微架构分析方法)对 CPU 性能优化的度量方式有两种,一种是 CPU 时钟周期,另外一种是 CPU Pipeline Slot,该方法假定每个 CPU 内核每个时钟周期 Pipeline 都是 4 个 Slot,即 CPU 的流水线宽是 4。
下图展示了各个时钟周期四个 Slot 的不同状态,注意只有 Clockticks 4 的 Cycle 利用率是 100%,其他的都是 Cycle Stall(停顿、气泡)。
对于一条 CPU 流水线来说,其在执行的时候有很多依赖,如下图所示:
从上图中可以看到,CPU 流水线执行的效率,依赖于其所依赖的资源的效率,通常可以总结如下:
Retiring: 表示运行有效的 uOps 的 Pipeline Slot,可以用于评估程序对 CPU 的相对比较真实的有效率。
Bad Speculation: 表示由于错误的预测导致浪费的 Pipeline 资源If/switch/while/for 都可能会产生 bad speculation。
Front-End-Bound: 取指令,解码,将指令发送给 back-end,每个周期最多分发 4 条 uops。
Back-End-Bound: 接受 front-end 提交的 uops,指令重排,从内存中获取数据,执行,提交结果到内存中。
对一个 CPU Pipeline 执行的评价指标,可以从以下几个维度去衡量:
Instruction Number: 指令数。当我们写一个 CPU 程序,终执行时都会被翻译成 CPU 指令,指令条数一般取决于程序复杂度。
CPI(Cycle Per Instruction): 执行一个指令需要的周期。
Clock Cycle Time: 一个 CPU 周期需要的时间,是和 CPU 硬件特性强关联的。
很明显,代码层面能优化的,是第一个和第二个维度,常用的优化手段包括:
相对于标量计算,SIMD 指令集能够极大地减少执行同一运算所需的指令次数,从而显著提升性能。这种性能提升是非常巨大的。接下来,我们来了解一下,什么是 SIMD。
SIMD 是指单指令流多数据流(Single Instruction Multiple Data)的计算模式。它是一种并行计算的技术,通过在单个指令中同时对多个数据元素执行相同的操作,从而实现高效的数据并行处理。
在 SIMD 计算中,一条指令可以同时对一个向量或者多个数据元素进行操作。这些数据元素通常被组织成向量寄存器,可以包含多个数据值,并且这些值会被同时处理。这种方式能够有效地提高并行计算的性能,尤其适用于需要对大量数据进行相同操作的情况。
SIMD 具有并行计算、数据局部性、硬件加速、高性能应用和节省能源等优势,使得它成为处理大规模数据和高性能计算任务的有效工具。
如下图所示,标量运算一次只能对一对数据进行加法运算,而采用 SIMD 指令,一次可以对多对指令同时进行运算。很明显,SIMD 指令能够大幅度提升数据的处理速度,且在处理列存的数据,具有巨大的性能优势。
SIMD 广泛应用于各种领域,如图像和视频处理、信号处理、科学计算和数据库等。它可以加速诸如向量加法、乘法、平均值计算、峰值检测等常见操作,从而显著提高计算效率。
PieCloudDB 针对执行器进行了颠覆性改进和优化,以便更好地利用 SIMD 的能力来处理大规模数据计算任务,进行向量化计算。PieCloudDB 通过将数据组织成向量形式,并使用 SIMD 指令来执行相同操作,从而使执行器能够在单个指令周期内同时处理多个数据元素,提高计算效率。
此外,针对不同类型的数据计算问题,PieCloudDB 还设计了针对 SIMD 的优化策略。例如,在聚合、扫描、连接和过滤等常见的数据计算操作中,PieCloudDB 利用 SIMD 指令集的并行计算能力,对关键节点进行了优化,以提升整体性能。
为了发挥 SIMD 的最大优势,并提高查询执行效率,对数据存储方式进行优化是关键。需要使数据存储更加友好于 SIMD 指令集的并行计算。
在关系型数据存储实现中,主要有两种数据存储的实现:
行存(Row-based): 即数据按行进行组织和存储。在行存中,每一行的所有列值都连续地存储在一起。行存具有紧凑型数据结构、一次读取整行、事务修改的原子性、适合点查等优势,但行存也存在一些缺点,包括额外的 I/O 开销,数据的碎片化等。
列存(Column-based): 即将每个列的数据连续存放在一起。相比传统的行存储方式,列存储具有以下优势:
➢ 数据压缩: 列存储可以应用更高效的压缩算法,减小数据存储的空间开销,并提高数据读取的带宽。
➢ 数据局部性: 由于列存储中每个列的数据是连续存放的,可以更好地利用处理器的数据局部性,减少指令和数据的 cache miss 率,提高访问效率。
➢ 数据 skip: 在列存储中,查询可以仅选择需要的列进行操作,减少不必要的数据传输和计算,提高查询效率。
但列存也存在一些缺点,例如选择(Selection)时按行读取,可能需要多次 I/O 操作。
下面以简单的数据表举例区别行存和列存。
使用行存的话,数据在内存和磁盘中的组织形式如下图所示:
如果使用列存的话,数据在内存和磁盘中的组织形式如下图所示:
PieCloudDB 目前的存储实现为行列混合存储。这种混合存储的方式结合了行存储和列存储的优势,以适应不同的查询模式和需求。方便用户在不同的业务场景下,选择不同的存储方式,达到效率的最大化。且列存将数据按列存储,使得连续的数据可以更好地利用 SIMD 指令的并行计算特性,完全发挥 SIMD 所带来的性能优势。为了最大程度地发挥数据处理的价值,特别是结合 JANM 存储系统已经支持的列存特性,PieCloudDB 执行器需要进行向量化计算优化。
PieCloudDB 云原生虚拟数仓采用全新的 eMPP(elastic MPP)架构,作为一款关系型数据库,其查询执行严格按照关系代数来实现,目前数据传递的方式是基于 Tuple 进行数据处理的,并采用火山模型作为具体的执行模型。这种上层算子递归调用下层算子获取并处理元组的方式存在一些缺陷,包括虚函数调用次数较多、指令或数据 Cache Miss 率较高等。同时,使用这种一次处理一个元组的方式无法充分利用 CPU 的 SIMD 指令进行优化,导致查询执行效率低下的问题。
而 SIMD 指令集能够同时处理多个数据元素,与列存技术相结合,能够实现更高效的数据处理。列存技术将数据按列存储,使得连续的数据可以更好地利用 SIMD 指令的并行计算特性。
为了打造向量化执行器,实现 SIMD 优化,需要考虑以下方面:
向量化操作: 重新设计和优化执行器,以支持 SIMD 指令集的向量化操作。通过重构代码逻辑,使用 SIMD 指令来处理整个数据列,而不是逐个处理每个元组。
数据布局优化: 根据 SIMD 指令集的特性,优化数据的存储方式和布局。通过进一步优化列存储,确保连续的数据可以充分利用 SIMD 指令的并行计算能力。
平台适配: 针对不同的硬件架构和 SIMD 指令集,进行适配和优化。考虑特定平台的限制和要求,确保 SIMD 优化能够在不同环境中有效实施。
通过这些优化措施,PieCloudDB 的执行器可以更好地利用 SIMD 指令集的并行计算能力,加速数据处理速度,提升系统性能和效率。这样可以在 OLAP 场景下实现更快速、高效的数据处理,充分发挥数据处理的最大价值。
向量化执行器的向量化处理的方式有很多种方法,比如可以对某些关键的处理流程进行 SIMD 代码优化,数据处理;使用对 SIMD 友好的 Hash Table 等。而 PieCloudDB 最终选择决定颠覆性重写一个全新的向量化执行器,主要基于以下方面的考虑:
足够优秀的现有执行器: PieCloudDB 现有的执行器在许多 OLAP 场景下已经表现出很高的性能优势,并完成了很多 HTAP 功能,在某些 OLTP 场景下也具有一定优势。
局部优化无法充分发挥 SIMD 的最大优势: 通过重写全新的向量化执行器,PieCloudDB 可以更好地利用 SIMD 指令集的并行计算能力,进一步提升数据处理性能。
进一步的计算形态建设: 在全新的执行器中,PieCloudDB 将更方便地实现湖仓一体和流批一体的计算形态建设,从而更好地适应不同的计算场景和各种数据处理需求。
拥抱大数据计算生态: PieCloudDB 作为拓数派大模型数据计算系统(πDataCS)的首款计算引擎,通过重写全新的向量化执行器,可以做到更好地与大数据计算生态进行对接和整合,为用户提供更广泛的数据计算解决方案。
PieCloudDB 团队相信重写全新的向量化执行器是必要且有益的,尽管这个过程可能会很艰难,但可以更好地赋能数据计算,实现极致的性能。经过反复的推敲与设计,PieCloudDB 向量化执行器的整体的架构图如下:
在启用向量化执行器后,当 plan-rewriter 收到优化器下发的查询计划时,将进行向量化算子的替换,并将替换后的查询计划发送给向量化执行器。如果不进行向量化,则会使用旧的执行器进行查询。
显然,向量化执行器的核心是上图右侧的各个算子,因此我们需要对这些算子进行大量改造,以充分发挥 CPU 的极致能力。为了实现这一目标,我们主要从以下几个方面进行 SIMD 改造:
行存变为列存: 通过将数据从行存储结构转换为列存储结构,可以提高 SIMD 指令集在数据访问和处理中的效率。这样,连续的数据可以更好地利用 SIMD 的并行计算特性。
行处理变为列处理: 将原本基于行的处理方式转换为基于列的处理方式。这涉及到对大量算法进行调整和改进,使其适应基于列的 SIMD 并行计算模型。这样可以提高数据处理的效率。
代码级别的优化: 在向量化改造过程中,我们需要进行代码级别的优化。这包括分支消除、代码结构调整等,以减少分支跳转和提高代码的连续性,从而提高 SIMD 指令的利用率。
数据结构的调整: 为了更好地适应 SIMD 处理,需要对数据结构进行调整。例如,可以替换传统的哈希表为更加 SIMD 友好的数据结构,以提高查找和插入操作的效率。
通过以上的向量化改造方向,将使得 PieCloudDB 在数据处理方面能够更好地发挥 CPU 的潜力,从而实现更快速、高效的数据计算。
PieCloudDB 向量化执行器在业内常用的决策支持基准测试 TPC-H 中展现了令人瞩目的性能提升,相较于原先的执行器,在关键节点上取得了数量级的提升,包括 Agg、Scan、Join、Filter 和 Expr Compute 等。
Agg: 使用向量化执行器能够更快地进行聚合操作,显著缩短查询的执行时间。对于需要对大量数据进行聚合操作的查询场景,这种提升尤为明显。
Scan: 向量化执行器能够加速数据的扫描和读取过程。通过利用 SIMD 指令集进行向量化操作,可以同时处理多个数据元素,提高数据访问和处理的效率。
Join: 向量化执行器能够更快速地执行表连接操作,处理多个表之间的关联。通过并行计算和向量化操作,可以加快 Join 操作的速度,提高查询的执行效率。
Filter: 向量化执行器能够更高效地处理查询中的过滤条件。使用 SIMD 指令集进行向量化操作,可以同时对多个数据元素进行条件判断,减少循环迭代次数,提高过滤操作的速度。
Expr Compute: 向量化执行器能够更快速地计算表达式和函数。通过利用 SIMD 指令集进行向量化计算,可以同时对多个数据元素进行表达式求值,加速计算过程。
这些关键算子数量级的提升使得 PieCloudDB 能够更快速地处理 TPC-H 基准测试以及日常 OLAP 场景中的复杂查询,提供更高效、更快速的决策支持能力。
后续我们将分别对这些算子的具体的优化过程进行剖析,欢迎大家关注!
行百里者半九十,PieCloudDB 向量化执行器的打造之路还在继续。目前,PieCloudDB 已经实现了 SIMD 指令集的支持,充分利用了数据并行计算的优势。通过将多个数据元素打包成向量,并同时对其执行相同的操作,成功提高了计算效率和吞吐量。
然而,我们深知这只是开始,我们将致力于进一步优化和改进 PieCloudDB 向量化执行器,以满足不断增长的需求和不断变化的技术环境,探索更高级别的向量化操作和更强大的 SIMD 指令集支持,以进一步提升数据库的性能和效率。具体方向包括:
PieCloudDB 向量化执行器的发展道路充满着挑战和机遇,我们坚信通过持续的创新和坚定的承诺,我们将继续前行,为用户带来更出色的性能和更广泛的应用场景。