向量化执行

ClickHouse实现了向量执行引擎(Vectorized execution engine),对内存中的列式数据,一个batch调用一次SIMD指令(而非每一行调用一次),不仅减少了函数调用次数、降低了cache miss,而且可以充分发挥SIMD指令的并行能力,大幅缩短了计算耗时。向量执行引擎,通常能够带来数倍的性能提升。

来个例子, sum函数

  1. num = 5
  2. a= 0
  3. for(int i =0;i<100;i++){
  4. a = num + i
  5. }

向量化引擎 - 图1

如上图所示:
  • 一个普通加法指令,一次只能对两个数执行一个加法操作。
  • 一个 SIMD 加法指令,一次可以对两个数组(向量)执行加法操作。

利用优点: 频繁调用的基础函数,大量的可并行计算尽量避免: SSE指令集对分支处理能力非常的差,而且从128位的数据中提取某些元素数据的代价又非常的大,因此不适合有复杂逻辑的运算。

比如 一个简单的LowerUpperImpl函数为例(这个函数完成大小写转换)就可以利用这个 clickhouse在处理分支的时候, 大量的使用了多线程来处理不同分支

要能够使用 Intel 的 SIMD 指令集, 需要当前 Intel 处理器的硬件支持

  1. grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"
  2. 如果你的机器支持SSE4.2,那么,将打印:
  3. SSE 4.2 supported
  4. 不使用SSE的版本的耗时总是使用SSE的版本的3倍多,鉴于ClickHouse在很多地方都渗透了SIMDSSE
  5. 积少成多每个细微的执行都这样,效率提升自然就非常可观了。
  • 向量化执行,可以简单地看作一项消除程序中循环的优化。
  • 现代计算机系统概念中,向量化执行是通过数据并行以提高性能的一种实现方式(其他的还有指令级并行和线程级并行),它的原理是在CPU寄存器层面实现数据的并行操作。
  • 为了实现向量化执行,需要利用CPU的SIMD指令。
  • SIMD的全称是Single Instruction Multiple Data,即用单条指令操作多条数据。
  • ClickHouse目前利用SSE4.2指令集实现向量化执行

前提条件

首先向量化执行引擎效率的发挥需要数据库能够提供列存的支持。 对于传统的行存表来说,谈向量化执行是不可能的。通常向量化执行引擎都是用在OLAP数仓类系统,因为通常分析型系统通常都是数据处理密集型负载,基本上都是采用顺序方式来访问表中大部分的数据,然后进行计算,最后将计算结果输出给终端用户。对于典型的OLTP点查询,这种类型的查询执行,使用行存表反而比列存表更好