矢量化执行

矢量化是把一个算法的一次处理一对操作的标量(非向量)实现转化为一次处理多对操作的向量实现。

假设在32核心上并行化算法,每个核心有4-wide SIMD寄存器。

SIMD就是单指令多数据流,是一类指令集,允许处理器同时在多个数据点执行相同的操作。

来看单指令单数据流SISD和SIMD的对比


单指令多数据流.png
单指令单数据流.png

SIMD介绍

数据的移动:在向量寄存器中移入移出
算数计算:能够在多个数据项上计算(比如2 doubles, 4 floats, 16 bytes) ADD, SUB, MUL...
逻辑指令:能够在多个数据项上进行逻辑运算,ADD, OR...
比较指令:在多个数据项上进行比较(==,<,>...)
Shuffle指令:在SIMD寄存器之间移动数据
转换:数据在x86和SIMD寄存器间进行转换
Cache控制:把数据从SIMD寄存器直接移动到内存而绕过CPU cache

SMID优缺点
优点:算法如果能够向量化可以获得显著地性能提升和对资源的利用率
缺点:用SIMD实现一个算法主要还是手动过程;SIMD会限制数据对齐alignment;把数据收集到SIMD寄存器并放到正确的位置很难效率也低。

针对上面的缺点,有三种解决方法
使用简单<--->编程控制

  1. 自动矢量化:编译器会识别循环中的指令能不能重写为向量化的操作。这只在简单的循环中起作用,但是在数据库操作中是很少见的。需要硬件支持SIMD指令
void add(int *X,
                    int *Y,
                    int *Z) {
    for (int i=0; i<MAX; i++) {
    Z[i] = X[i] + Y[i];
    }
}

这个循环不能自动矢量化。XYZ可能指向同一个地址,那么对于循环中的指令它们就是有关联的,对于编译器它不知道应该直接写Z并且重写XY,还是按照顺序执行。

  1. 编译器提示:用额外的信息告诉编译器这部分代码是可以安全的矢量化的。
    实现上,可以给出关于内存地址的明确信息;或告诉编译器忽略向量依赖。
void add(int *restrict X,
                    int *restrict Y,
                    int *restrict Z) {
    for (int i=0; i<MAX; i++) {
        Z[i] = X[i] + Y[i];
    }
}

这里的restrict关键字就是告诉编译器XYZ在内存中不同的位置。
或者是在void add(int *X, int *Y, int *Z){后面加#pragma ivedp,忽略循环内的向量依赖(需要自己判断是否正确)。

  1. Explicit矢量化:用CPU内部函数手动处理SIMD寄存器之间的数据并执行矢量化执行。
    移植性差
    __mm128i vecX = (__m128i)X;
    直接把向量存到128位SIMD寄存器中,调用内部函数将矢量相加,并写入输出位置
    ......然后是很魔幻的操作,看不懂是啥

矢量化DBMS算法

用基本的矢量化操作构建更高级的功能的高效矢量化原则

  • 通过处理每个lane(可以理解为列)的不同输入数据来支持垂直向量化。
  • 通过每个lane的子集执行不同的事情来最大化lane利用率。

基础操作

Selective Load 与 Selective Store


vector表示寄存器中的数据
通过mask来表示寄存器中哪些数据需要导入、导出。

Selective Gather和scatter
按顺序导入或导出
gather和scatter不是真正的并行执行,因为L1缓存每个周期只允许一个或两个不同的访问。

矢量化操作

Selection Scans

调度与执行中讲过CPU的分支处理

SELECT * FROM table
  WHERE key >= $low AND key <= $high

标量有分支和无分支
现在多了一个矢量的



将key向量加入SIMD寄存器中进行SIMD比较,产生mask,再进行SIMD Store
这里虽然也有if(?比较符),但是它比顺序执行快,因为它可以进行批量的比较。
对于DSM列存储更有优势,可以通过一个load把整列加入一个SIMD寄存器,输出的结果也不用存储key的值,只需要存它的offset。

哈希表

在线性探测法的哈希表中,对于每个元组需要计算它的哈希值,然后通过线性扫描找到正确的地址。
水平矢量化的方式是在hash表中直接存了一组值作为key,然后用SIMD compare对比K1和向量中的所有值,产生mask,如果没有匹配再用线性开放寻址解决冲突。
垂直矢量化是同时hash多个key,分别映射表哈希表中。 或者是通过SIMD Gather同时查询多个值。一次查询多个值会统一返回查询结果,通过直接比对值和查询的结果得到mask,mask为0的需要再次查询。

Partitioning


h2和h4指向同一个位置,发生冲突,用复制直方图解决冲突。


矢量化查询对于OLAP查询至关重要。
当数据超出CPU cache这些算法就不起作用了。
把所有intra-query并行优化结合起来:

  • 同一个查询多个线程同时处理
  • 每个线程都能执行一个编译的plan
  • 编译的plan能调用矢量化操作

矢量化和编译都能加速执行,现在讨论在什么条件下这两种方法更好。

原语是操作系统的核心,内核或微核提供核外调用的过程或函数称为原语(primitive)。由若干条指令组成,来完成一定功能的过程,执行必须过程连续,不允许被中断
重点 - - 原子语句,不可分割,执行不可中断(要么全部执行,要么都不执行)

矢量方向——预编译的原语
预编译数千条元组在类型数据上进行基本操作(对每个原语用简单的核意味着他们更容易矢量化)

DBMS执行查询计划时会调用这些原语

  • 函数调用是分摊到多个元组的
  • 一个元组的输出是元组的偏移量


    一个查询的原语表示

Hyper-JIT查询编译
用LLVM在内存中把查询编译成本地代码,尽可能将元组存在CPU寄存器中

  • 由底向上/push-based查询处理模型
  • 不可矢量化

矢量化 vs. 编译

Everything You Always Wanted to Know About Compiled and Vectorized Queries But Were Afraid to Ask这篇论文
讲的是如何测试和测试的结果,不再写了
用于测试矢量化执行和查询编译之间的权衡的测试台

在同一个系统中用两种方法实现一个高级算法的方式不同

  1. Tectorwise:把操作分解成预编译原语;必须把每一步元组的数据给物化
  2. Typer:用JIT编译的Push-based处理模型;处理一个元组完全用pipeline而不物化中间结果

实验发现:两个模型都很高效,性能基本一致;Data-centric对高计算的查询更好,因为会更少的cache miss;矢量化在隐藏cache未命中延迟稍好一些。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352