864
Journal of Software 软件学报 Vol.32, No.3, March 2021
模块,将 SQL 直接编译为 CUDA 或 OpenCL 驱动能执行的代码,以算子为单位进行即时编译
[19].
适配器
模式在运行时的编译负载会比较高,在提高了系统对显卡种类多样性的同时,牺牲了针对特定显卡的
性能优化,需要结合查询并行、分布式计算等技术来提升性能.此外,为应对 GPU 硬件的多样性,尤其是
为弥合 NVIDIA 显卡和 AMD 显卡两家处于竞争中的两种架构之间的不同,Ocelot
[35]
等系统使用
OpenCL 框架,避免为 GPU 不同架构分别编写代码造成的代码膨胀问题.
基于 LLVM 中间表示的 GPU 通用编译工具能够很好地隔离硬件多样性,做到编译各阶段彼此孤立,给
GDBMS在编译的各个阶段进行优化提供了可能.未来,基于编译自动化工具的研究将极大提升 GDBMS系统的
性能.
2.2 GPU数据处理模型
数据库中,从数据处理模型来看,可分为 3 种:迭代模式(iteration)、批量模式(batching)或二者的混合.传统的
DBMS 往往采用一次一行的流式迭代模型,也就是著名的火山模型(volcano model)处理查询请求.时至今日,研
究界和工业界提出了各种改进版的火山模型来规避其缺点,比如增加每次迭代的数据量、使用 SIMD 指令一次
处理多个数据、推拉结合的数据获取方式等,目前仍然是数据库中的主流编译技术.批量模式是将每个查询编
译为可执行代码,采用完全物化的方式处理所有数据.批量模式相较火山模型的迭代模式,在提高局部性、减少
运行时解释开销、使用 SIMD 指令方面有很大优势,但在实现 ad-hoc 查询上,面临灵活度不够、物化存储空间
要求过高的问题.因此,实践中将两者结合的方式更有优势,比如微批量化查询处理.该类方案使用不同的粒度
作为数据处理的单元,仍然在逻辑上组织成树型结构,让数据自底向上流动完成查询操作,兼具迭代模型的灵活
性和批处理的高吞吐量的优点.
GDBMS 普遍采用向量化一次一算子数据处理模式,并以此改造查询编译器.
• 首先,迭代模式并不适合 GDBMS,因为火山模型赖以存在的虚函数机制因为 GPU 缺乏对应的复杂逻
辑控制模块,在 GPU 上不可实现或者引起严重的线程分支恶化问题.迭代模型的灵活性是“彼之蜜糖,
我之毒药”,实际上会损害 GPU 的性能.GPU 的 SIMT 采用大规模线程并发的方式来提高数据处理的速
度,批量执行可以有效降低生成计划的函数调用次数,将列数据细粒度分配给 GPU 线程,并用循环展开
的方式,可有效减少控制指令总量,有效降低分支恶化的风险;
• 其次,列式处理更适合 GDBMS.一次一行的处理数据方式在代码上需要做大量的逻辑判断,而这正是
GPU 的劣势;一次一列来处理数据时,由于每列数据类型一致,可以用向量化方式处理,避免了分支判
断劣化性能问题,更适合 GPU 计算.此外,有研究
[36]
证实:对于 OLAP 业务,按行为单位的处理模型即使
行被合理分区并增加列索引等优化策略后,仍然不如列式处理高效.事实上,列式处理模型自
MonetDB
[37]
首次引入后,其后续系统 X100
[38]
将流水化(pipelining)引入列式处理模型中.GDBMS 系统
普遍采用列式处理模型
[30]
,比如 Ocelot
[13]
,CoGaDB
[10]
等;
• 再次,由于 GPU 的大规模并行编程模型依赖于对数据的并行处理,很多算法想在 GPU 上运行必须适应
单指令多线程(SIMT)的编程范式,所以需要对关系算子进行并行化改造,使得同一指令同时处理多个
关系数据处理需求,充分利用 GPU 的并发编程优势.“一次一算子”的数据处理模式就是:让数据在 GPU
向量化算子间流动,每次采用完全物化的策略保存算子输出的中间结果,作为下一个算子的输入数据;
• 最后,为了降低物化代价,通过适当分区切分数据,可以使 GDBMS 兼具迭代模式的最大的优点——流
水化处理数据的能力
[39]
.为了加速数据处理以及利用合理分区数据,采用数据流水化处理(pipelining
data processing),有效提高数据处理并行度.文献[40]通过细粒度划分数据,将处理整个列的算子切成更
小的算子单元,在 GPU 上实现了相关算子间流水化处理数据.
3 查询处理器
GDBMS 查询处理引擎接受处理查询编译器输出的查询计划树 QEP(query execution plan)并执行查询返回
结果,是利用 GPU-CPU 异构计算处理用户查询请求的核心模块.从功能角度来看,GDBMS 查询处理引擎面对的