编译器优化那些事儿(12):LLVM 自动向量化

文章介绍了在编程语言编译器优化中,如何利用向量化技术(如循环向量化和SLP向量化)将标量代码转化为向量代码,以提高性能。LLVM框架中的这两个向量化pass在循环迭代间和迭代内寻找并行计算机会。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

向量化是一种将程序中标量代码转换为向量代码的优化手段。当前很多芯片架构都拥有向量计算单元,架构指令本身支持单指令多数据(SIMD)的并行计算,一条指令同时计算多个数据。使用向量化优化后,可以实现一个cycle计算多个标量数据,从而带来巨大的性能提升。

在LLVM框架中有两个自动向量化pass:循环向量化(Loop Vectorizer)和 SLP向量化(Superword-level Parallelism)。其中循环向量化关注循环迭代间的向量化机会,会使循环的迭代次数减少,单次迭代的计算数据量增大。而SLP向量化关注迭代内的向量化机会,会将单次迭代中的相似标量计算/访存等操作合并为一条向量指令,也就是减少单次迭代内的指令生成数量。

这两个向量化pass都在LLVM中端opt部分执行,其中SLP向量化位置更靠后一些,在循环向量化完成且控制流图简化(CFG Simplify)后执行。

循环向量化

循环向量化扩展循环中的指令,转换的逻辑如下图所示。这个优化在LLVM中是默认开启状态,如果想要关闭可以使用 -fno-vectorize 选项。

#pragma clang loop vectorize_width(2)

for (…) {

}

1. 优化诊断

实际用户代码中,会有很多循环因为各种原因(比如:过于复杂的控制流、数据类型不支持等)无法完成向量化。LLVM提供了打印诊断信息的能力方便开发者调试,这些信息会提示一个循环向量化是否成功以及失败原因,不过失败原因可能不会非常细节。

以下方循环为例,这个循环使用 #pragma 指定要做向量化,但是循环中有个向量化不支持的switch语句,所以会向量化失败。

#pragma clang loop vectorize(enable)

for (int i = 0; i < 128; i++) {

    switch (A[i])

}

LLVM提供的的优化诊断有三种:

(1)-Rpass=loop-vectorize&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值