共计 2610 个字符,预计需要花费 7 分钟才能阅读完成。
在软件基础设施畛域,人们开始越来越器重代码的性能优化,在满足其可实现性能残缺的同时,若可逐渐去优化代码,则能在雷同硬件条件下达到更好的工作效率,进一步提高业务生产效率。尤其是大数据畛域,比方 OLAP 数据库通常服务于海量数据即席查问剖析的场景,一些看似不起眼的底层调优却能在数据量级上进行优化叠加,从而达到优化零碎整体剖析查问的性能目标,堪称星星之火能够燎原。
在这里次要向大家做一个 Databend 性能调优相干的分享,共会分为三次向大家介绍,如下所示:
1、根底篇:代码调优的前置常识
2、实际篇 1:Databend 源码性能调优实际
3、实际篇 2:Databend 的 Group By 聚合查问为什么跑的这么快?
在后续 Databend 打磨的过程中,咱们也将介绍更多对于性能优化相干的设计,比方 Databend 新的 pipeline workflow 模型设计,Databend 如何将向量化和编译执行联合等。
对于本系列课程的视频回放,能够点击 https://www.bilibili.com/vide… 查看~
1、存储器层次结构
随着科技的一直倒退,大家肯定对存储器越来越不生疏了,下图中所出现的内容为存储器的金字塔模型。
图中存储器层次结构从上往下为:寄存器、L1 Cache、L2 Cache、L3 Cache、内存、SSD/HDD 硬盘。每个层次结构都有着不同的容量、缓存工夫。从上往下来看,存储容量越大,但速度越慢,老本越低,往上来看则相同。通常编写高性能代码的准则在于将数据拜访凑近下层,让数据离 CPU 凑近,缩小数据拜访的开销。
2、提早
上图理解了通用的存储器,咱们再来介绍下存储器大略的拜访提早。提早也示意为实现计算或者 I/O 申请所需的工夫,为了量化这个指标,也会通过各种计算来掂量这个性能,例如 IOPS、吞吐量等等。
下图 [1] 为大家列出几个每个程序员都应该理解的提早数字,这些数字代表了计算机各类操作的一个大略耗时:
Jeff dean 曾要求这些提早所有程序员都应该熟记于心,它让咱们在代码调优的时候能有一个主观的度量值。
3、局部性原理
基于古代计算机存储器的设计,程序在执行的过程中存在着很强的局部性,局部性又分为了「工夫局部性」和「空间局部性」。
工夫局部性:
工夫局部性是指当一个数据在某一时间被拜访后,则有可能在不久后被再次拜访,所以咱们看到很多程序会利用缓存来减速数据拜访。
空间局部性:
也称数据局部性,得益于存储器缓存的设计,它是指当一个数据在某一地址被拜访了之后,则拜访它相邻地位的数据也会更加高效,常见于循环拜访数组数据中。
所以当咱们利用好这些局部性原理,能够编写更加“局部性”的代码来晋升 CPU 的性能和利用率。下图中展现为英特尔公司的 Core i7 Haswell 处理器的存储器山模型,x 轴示意存储器的容量大小,y 轴示意程序拜访的步长,z 轴示意存储器拜访吞吐,其 3D 模型则为图中所示。
随着存储器的容量晋升,性能根本呈倒退趋势,但如果步长能够在肯定短的区间内,能够十分好利用数据局部性的优化,比方 CPU 的 prefetch,从而达到晋升吞吐的作用。
4、数据局部性示例
这里再介绍一个矩阵的行优先和列优先遍历拜访的例子,咱们遍历矩阵求和的形式是先循环行形式遍历还是先循环列形式进行遍历。如图所示,在 Row-major order 中,行遍历求和的性能远高于列遍历求和的性能,因为行遍历的形式数据能有更好的局部性,相邻的数据能够在 CPU cache 中,数据能够以十分高效的形式拜访。同时,编译器也能对局部性强的数据拜访进行优化,生成更加高性能的代码,比方主动向量化。
5、性能表白
这里援用 CASAPP [2] 中 Prefix-sum functions 的例子,在 psum1 函数中做的是间接应用一个 for 循环做加总求和,在 psum2 中,对循环进行开展,步长为 2 进行遍历。咱们对两个函数设置不同的循环次数,每次运行代码都能失去一个 CPU 时钟后果,将后果使用最小二乘法能够拟合成上面的两条直线,直线的效率对应的就是函数性能的开销。能够得出 psum2 的性能显著优于 psum1。
6、实用工具和脚本介绍
在根底篇的前面,介绍下 Databend 中常见的调优形式。
Print & Log & Tracing metrics
(1) 最常见的还是通过日志打印耗时,或者将耗时输入到监控零碎中
(2) prometheus, jaejer [3]
Perf is a good tool, pprof, flamegraph
(1) How to profile databend [4]
(2) Cargo flamegraph crate [5]
- cargo bench & criterion [6]
- databend-benchmark [7]
- ignore function && progress [8]
本文 ppt 地址:
[1]https://github.com/datafusela…
[2]https://github.com/wubx/rust-…
7、文章相干援用
[1]https://colin-scott.github.io…
[2]CS:APP3e, Bryant and O’Hallaron (cmu.edu)
[3]ISSUE-3627: adding distributed tracing instrumentation to query by dantengsky · Pull Request #3628 · datafuselabs/databend (github.com)
[4]How to profile Databend | Databend
[5]flamegraph-rs/flamegraph: Easy flamegraphs for Rust projects and everything else, without Perl or pipes <3 (github.com)
[6]bheisler/criterion.rs: Statistics-driven benchmarking library for Rust (github.com)
[7]databend/databend-benchmark.rs at main · datafuselabs/databend (github.com)
[8]databend/perfs.yaml at 9393f5cf7da5827132acd479185878726caf58bf · datafuselabs/databend (github.com)