如何触发编译器的自动化

1、SIMD 简介

SIMD 是 Single Instruction Multiple Data 的缩写,指单个指令可以操作多个数据流,与之相对的是传统的 SISD,单指令单数据流。

如上图所示,对于最简单的 A + B = C,假如我们要计算 4 组加法,传统的 SISD 需要执行 8 次 Load 指令 (A 和 B 分别 4 次)、4 次 Add 指令、4 次 Store 指令。但当我们使用 128 位宽的 SIMD, 我们只需要 2 次 Load 指令、1 次 Add 指令、1 次 Store 指令,这样理论上就可以获得 4 倍的性能提升。而目前的向量化寄存器位宽已经发展到 512 位,理论上 Int 的加法操作就可以加速 16 倍。

2、如何触发向量化?

如前文所述,SIMD 指令会带来巨大的性能提升,数据库开发人员自然需要理解并掌握如何进行 SIMD 编程。

如上图所示,SIMD 触发向量化一般有 6 种方式,这 6 种方式自顶向下,对工程师的要求越来越高,需要手动编写的东西越来越多。 

  • 第一种是编译器自动向量化,代码不需要做特殊处理和改动,编译自动将默认的标量代码转换成向量化代码。但编译器默认只能处理比较简单的程序,具体支持的 Case 大家可以在网上搜索,资料很多;

  • 第二种是我们给编译器一些 Hint,给编译器更多的信息和上下文,编译器也可以生成 SIMD 指令;

  • 第三种是使用像 OpenMP 或者 Intel Cilk 这种并行编程 API,开发者可以加一些 Pragma 来生成 SIMD 指令;

  • 第四种是使用一些 SIMD Intrinsics 的包装类;

  • 第五种是直接使用 SIMD Intrinsics 编程;

  • 最后一种是直接写汇编代码。

在 StarRocks 项目中,我们向量化的原则是尽可能触发编译器的自动向量化,也就是第一种和第二种,对于不能自动向量化但是性能又很关键的操作,我们会通过 SIMD Intrinsics 的方式手动向量化。

关于如何触发编译器的自动化,如何给编译器加 Hint 触发向量化以及如何通过 SIMD Intrinsics 的方式手动向量化大家可以参考我个人博客《数据库学习资料》向量化部分的资料,本文不再赘述。

《数据库学习资料》:https://blog.bcmeng.com/post/database-learning.html

3、如何验证程序生成了向量化代码?

当一个项目代码比较复杂时,如何确保代码触发向量化是很常见的问题。 我们可以通过两种方式来检查:

第一种是给编译器加一些编译选项,编译器会输出某些代码是否触发向量化,以及没有向量化的原因。比如 GCC 编译器,我们可以加入 -fopt-info-vec-all 或者 -fopt-info-vec-optimized,-fopt-info-vec-missed,-fopt-info-vec-note 编译选项。效果如下图所示:

第二种方法,我们可以直接查看最终执行的汇编代码,比如使用 https://gcc.godbolt.org/ 等网站或者 Perf、Vtune 等工具,如果汇编代码里面的寄存器是 xmm,ymm,zmm 或者指令以 v 开头,一般就说明代码触发了向量化。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值