向量化运算OLAP
Clickhouse、dorisDB(starrocks)、spark(2.x以后)、 hive(0.13.0以后)、presto
SIMD
SIMD全称Single Instruction Multiple Data,单指令多数据流,能够复制多个操作数,并把它们打包在大型寄存器的一组指令集。
前提需要支持SIMD的CPU才能发挥其特性。
性能上优势
以加法指令为例,单指令单数据(SISD)的CPU对加法指令译码后,执行部件先访问内存,取得第一个操作数;之后再一次访问内存,取得第二个操作数;随后才能进行求和运算。而在SIMD型的CPU中,指令译码后几个执行部件同时访问内存,一次性获得所有操作数进行运算。这个特点使SIMD特别适合于多媒体应用等数据密集型运算。
注: 上面的内存指的是CPU寄存器
什么是vectorization
向量化计算(vectorization),向量化计算是一种特殊的并行计算的方式,它可以在同一时间执行多次操作,通常是对不同的数据执行同样的一个或一批指令,或者说把指令应用于一个数组/向量
上图中,左侧为vectorization,右侧为寻常的For loop计算。将多次for循环计算变成一次计算完全仰仗于CPU的SIMD指令集,SIMD指令可以在一条cpu指令上处理2、4、8或者更多份的数据。
因此简单来说,向量化计算就是将一个loop处理一个array的时候每次处理1个数据共处理N次,转化为vectorization处理一个array的时候每次同时处理8个数据共处理N/8次。
向量化运算的实例
在Python的numpy库中使用向量化(Vectorization)计算,速度是非向量化(non-Vectorization)计算(即循环)的700倍(当前开发环境),因为向量化计算使用了python的内建函数,调用了CPU/GPU的SIMD指令集进行计算,大大减少了因为python高级语言执行损耗的时间。
实例:
import numpy as np
import time
cnt=10000000
a = np.random.rand(cnt)
b = np.random.rand(cnt)
tic = time.time()
c = np.dot(a, b)
toc = time.time()
print("c: %f" % c)
print("vectorized version:" + str(1000*(toc-tic)) + "ms")
c = 0
tic = time.time()
for i in range(cnt):
c += a[i] * b[i]
toc = time.time()
print("c: %f" % c)
print("for loop:" + str(1000*(toc-tic)) + "ms")
结果;
c: 2499089.213332
vectorized version:5.998373031616211ms
c: 2499089.213332
for loop:4685.6348514556885ms