CPU与代码向量化

首先感谢来自tidb徐老师的讲解!此文记录一下看完视频后的读后感。
论文地址:原文
论文备份:百度云 提取码:fxde
视频地址:视频:解读论文《Everything You Always Wanted to Know About Compiled and Vectorized Queries But Were Afraid to Ask》

向量化

What?

首先,什么是向量化?这里主要运用到的是一维的向量,学过线性代数可能知道,一维的向量都是一类的,例如高度、长度、重量。我们可以用一个一维的向量表达多个object的某一个属性,表现到代码里面的就是数组。

Why?

首先要提到两个概念。

  • 行存储(row store):处于同一行的数据连续存储;比较有利于整行数据读取的操作。
  • 列存储(column store):处于同一列的数据连续存储;比较有利于列数据运算的操作。

为什么需要向量化?在关系型数据库当中,OLTP(Online Transaction Processing)数据库一般是按行存储(row store)的,意思就是同一行数据在存储空间当中是连续的。

下面会举个例子:
在下表中执行:select * from age > 15 and tall < 176

id name age tall
1 anker 25 175
2 john 12 165
3 andy 33 178

非向量化代码主要是会拿到了同行的其他无用数据,这对于CPU缓存极度不友好,会造成频繁缺页(page)。

非向量化代码(golang)

func where(rows []*Row) []*Row {
    var result []*Row
    for _, row := range rows {
        if row.age > 15 && row.tall < 176 {
            result = append(result, row)
        }
    }
    return result
}

向量化代码(golang)

func whereAge(cols []*Col) []int {
    selectedCol := make([]int, 0)
    for i, colValue := range cols {
        if colValue > 15 {
            selectedCol = append(selectedCol, i)
        }
    }
    return selectedCol
}

func whereTall(cols []*Col, selected []int) []int {
    selectedCol := make([]int, 0)
    for _, index := range selected {
        if cols[index].tall < 176 {
            selectedCol = append(selectedCol, index)
        }
    }
    return selectedCol
}

你可能感兴趣的:(CPU与代码向量化)