Apache Doris 向量化技术实现与后续规划

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. Doris 向量化技术实现与后续规划 李昊鹏
2. Contents • Doris向量化的设计与实现 • Doris向量化的当前情况 • Doris向量化的未来规划
3. 01 Doris向量化的设计实现
4. 什么是向量化? • 向量化:计算由一次对一个值进行运算转换为一次对一组值进行运算的过程 • CPU角度:现代CPU支持将单个指令应用于多个数据(SIMD)的向量运算。 例如,具有128位寄存器的CPU可以保 存4个32位数并进行一次计算,比一次执行一条指令快4倍。 SIMD
5. 什么是向量化? • 向量化:计算由一次对一个值进行运算转换为一次对一组值进行运算的过程 • 数据库执行引擎:1.将next tuple,变成next batch。2. 内存中batch的数据不是以行的形式存在,而是以列的 形式存在,算子都是在列上进行运算。
6. Doris如何实现向量化 • 列式存储:在Doris的执行引擎之中引入基于列存的存储格式 • 向量化函数计算框架:基于列式存储重新设计一套向量化/列式计算引擎 • 向量化算子:基于前两者,重新组织SQL算子。
7. 列式存储 • 改变了计算引擎对数据的组织方式,由行存的Tuple与RowBatch变为了Column与Block
8. 向量化函数计算框架 举个栗子: • 需要计算一个select a,abs(b) from test;
9. 向量化函数计算对比 相比原先的行存执行逻辑,限制减少了分支判断的次数 // 行存执行逻辑 for(int i = 0;i < rows; ++i) { Tuple tuple = batch->get_row(i); for(int j = 0;j < desc.slots().size();++j) { void *data = tuple.get_data(desc.slots(j).offset); // 获取某 一行的数据 switch(desc.slots(j)) { // 通过desc中的描述类型来确定执 行逻辑 case TYPE_INT: hash_int((int*)data); case TYPE_STRING: hash_string((StringRef*)data); // 列存执行逻辑 for i in range(types.size()) switch(types[i]) { // 只有一次的类型判断 TYPE_INT: for(j = 0; j < rows < ++j) { hash_int((*(int*)column->data() + j)); } TYPE_STRING: xxx;
10. 向量化计算优点 相对于旧的行存计算框架,列式的函数计算框架有以下优势: • Cache更亲和,列式计算由于数据是按列组织的,所以更容易命中Cache。从Cache中读取 数据和内存中读取数据,性能有10到100倍的差距 • 减少虚函数的调用,减少分支跳转,降低CPU分支预测判断失败概率 • 函数计算的SIMD,包含编译器自动SIMD与手动Coding的SIMD 论文《DBMSs On A Modern Processor: Where Does Time Go?》,时间都去哪啦? • Memory stalls • Branch mispredictions • Resource stalls
11. Cache亲和度 Cache的开销与代价: • 指令Cache/数据Cache/TLB的Cache • L1/L2/L3/DDR -> 1/5/20/100 ns • 内存带宽
12. 虚函数的调用开销 虚函数会有怎么样的开销: • 虚函数的动态调用是无法进行函数内联的,这会大大减少编译器可能进行的优化空间 • 虚函数查表带来额外的分支跳转的开销,分支预测失败会导致CPU流水线重新执行
13. 函数执行如何SIMD • Auto Vectorized 自动向量化,也就是编译器自动去分析for循环是否能够向量化。GCC开启的-O3优化便会开启自动向量化。 下面是自动向量化的一些tips: 1.简单的for循环 2.足够简单的代码,避免:函数调用,分支跳转 3.规避数据依赖,就是下一个计算结果依赖上一个循环的计算结果 4.连续的内存与对齐的内存 GCC的文档CASE:https://gcc.gnu.org/projects/tree-ssa/vectorization.html
14. 函数执行如何SIMD • Auto Vectorized 如何确认代码编译器的自动向量化生效呢? 1.编译器的Hint提示 -fopt-info-vec-all:打印所有编译器进行向量化的信息,如果循环代码被向量化了,会打印如下信息 main.cpp:5: note: LOOP VECTORIZED. -fopt-info-vec-missed:没有被向量化的原因 -fdump-tree-vect-all:进一步分析没有被向量化的原因 2.直接通过perf/objdump查看生成的汇编代码
15. 函数执行如何SIMD • 手写SIMD SIMD本身也通过库的方式进行了支持。可以直接通过向量化的API库来直接进行向量化编程, 这种实现方式最为高效,但是需要程序员熟悉SIMD的编码方式,在不同的CPU架构之间并不通用。比如实现的AVX 的向量化算法并不能在不支持AVX指令集的机器上运行,也无法用SSE指令集代替。
16. 02 Doris向量化的当前情况
17. SQL算子 目前0.15版本实现向量化的SQL算子包含: • Sort • Agg • Scan • Union 当前的Doris是能够满足大宽表的向量化查询需求
18. 如何开启向量化 1. 设置环境变量set enable_vectorized_engine = true;(必须) 2. 设置环境变量set batch_size = 4096; (推荐)
19. 向量化的单表性能 Q1:select count(*) FROM lineorder_flat; Q2:select min(lo_revenue) as min_revenue from lineorder_flat group by c_nation; Q3:select count(distinct lo_commitdate), count(distinct lo_discount) from lineorder_flat;
20. 03 Doris向量化的未来规划
21. SQL算子 • Join是Doris最为核心的算子,绝大多数场景使用Doris也是看重了Doris本身在MPP场景下的 多表Join能力。所以Join的开发是后续向量化开发重中之重。
22. SQL算子 • 交集 • 差集 • Cross Join • ODBC/MySQL Scan Node • 窗口函数 • ES Scan Node 这些算子都是当前行存所支持的,目前除了部分算子还在开发过程中,其他也都全部Ready了
23. 存储层向量化 目前Doris存储层通过行存表示数据,但是由于历史原因这部分存在很多冗余且低效的代码 目前 看已经严重影响了向量化代码的执行逻辑。 • 1. 计算表达式受限制,部分表达式的计算由于接口不同,无法作用于存储层,导致很多表达式 无法下推。 • 2. 额外的转换的性能开销,严重影响了导入与查询性能。在之前进行的poc测试之中, DupKey 的表透过完整的向量化改造之后,性能有10倍级别的提升。 • 3. 代码可维护性降低,同样实现一个聚合代码需要分别在存储层和查询层实现,性能优化等也 需要同时考虑两部分。
24. 存储层向量化 • Reader层改造 (WIP) • Segment层改造 (WIP) 查询 Origin 向量化第一版 存储层向量化 Q1 3.48 0.45 0.2 Q2 10.5 0.75 0.37 Q3 0.58 0.25 0.12
25. 导入向量化 目前Doris进行数据导入时存在Tuple转RowCursor,数据行式聚合等一系列有冗余开销的的工 作。而我们后续希望通过导入向量化的开发,实现: • 1. 减少额外内存格式的转换开销,提高CPU的利用率 • 2. 复用计算层的算子,减少冗余低效的代码,简洁Doris现有的代码结构 • 3. 利用SIMD加快导入过程之中的聚合计算,进一步提升Doris的导入性能
26. SQL函数 • 1. 函数丰富度的支持,目前向量化支持的函数大概有200多个,其他还在不断的开发过程中。 需要尽快补齐原先行存支持但是向量化不支持的函数。 • 2. 函数的SIMD化,目前向量化很多函数的实现没有考虑SIMD化。对于核心的热点函数,后 续要尽量能够通过各种可能的方式SIMD化。 • 3. 向量化的UDF的框架设计
27. 代码重构 • 1. 基础类型的重构: • Date/DateTime:更小的内存占用,对SIMD更优化的内存布局 • Decimal:根据精度切换内存占用,解决Doris中当前精度浪费的问题 • HLL:减少HLL类型无效的序列化的开销 • 2. String/Array 类型的支持 • 3. 聚合表类型的再梳理,更合理的设计聚合列的类型和状态 • 4. 结合Doris团队在打磨的CBO优化器,进一步提升向量化执行引擎的性能
28. 其他 • 1. 版本发布,如果顺利的话。1月份我们将会带来下一版的向量化执行引擎了,希望大家到时 候多多试用捧场~~ • 2. 感谢Clickhouse社区,在Doris进行向量化代码开发时在列存模型与函数框架上引用了部分 Clickhouse 19.16.2.2的代码,在引用代码的lisence上注明了相应的工作。
29. Thank You 欢迎关注Doris微信公众号 更多技术趋势、实践案例、社区活动 • Apache Doris官网:https://doris.apache.org/master/zh-CN/ • GitHub:https://github.com/apache/incubator-doris • GitHub向量化:https://github.com/doris-vectorized/doris-vectorized • 百度发行版本:palo.baidu.com

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.137.1. UTC+08:00, 2024-11-16 07:50
浙ICP备14020137号-1 $Map of visitor$