0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RISC-V架构下的编译器自动向量化

进迭时空 ? 2025-06-06 16:59 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

进迭时空专注于研发基于RISC-V的高性能新AI CPU,对于充分发挥CPU核的性能而言,编译器是不可或缺的一环,而在AI时代,毫无疑问向量算力将发挥越来越重要的作用。进迭时空非常重视RISC-V高性能算力生态的建设,正投入编译器自动向量化优化等多项关键技术,全面助力RISC-V的高性能发展。

RISC-V 向量设计

SpacemiT

在现代CPU中,向量支持是算力的一个重要组成部分。1996年Intel就推出了针对多媒体应用程序设计的SIMD指令集MMX,随后又逐步引入了SSE、AVX、AVX2、AVX-512,Arm也引入了NEON指令集支持,并在armv8版本中将NEON定义为默认支持,后续又引入了长度可变的SVE。

对于新兴的RISC-V架构, 同样也有vector扩展支持。RISC-V Vector Extension(下文简称RVV)是 RISC-V 指令集架构(ISA)中的一种扩展,专门设计用于高效的向量处理。RVV 为RISC-V 指令集架构引入了强大的向量处理能力,旨在通过向量化计算提高多种应用程序的计算性能。

808cfb54-42b4-11f0-986f-92fbcf53809c.png

吸收了其他架构的经验,RISC-V发现传统的SIMD指令设计并不够好,不同的宽度引入不同的SIMD指令,使得整个指令集越来越庞大和复杂。RISC-V的发明人Patterson教授在《SIMD Instructions Considered Harmful》一文中阐述了这一观点。

最终RVV的设计更类似于SVE,是可变长的向量,而且非常灵活,可在运行时动态设置寄存器大小,分组,宽度,以及掩码操作等,可以做到同一份二进制文件在不同VLEN的硬件上都能充分发挥硬件性能。

其灵活的设计和易于编程的特性,使其在现代计算任务中具有明显的优势,并为未来的计算需求提供了良好的支持。随着 RISC-V 生态系统的发展,RVV 有望在更多应用中发挥重要作用。

自动向量化

SpacemiT

如何利用向量算力,一种方式是软件开发者直接调用向量的编程接口,另一种方式是直接编写标量代码通过编译器实现自动向量化,这两种方式各有优劣,都不可或缺。

向量化(Vectorization)是一种编程和编译优化技术,自动向量化的本质是编译器识别程序中的循环或者基本块,将多个标量操作组合在一起,利用编译器数据流/控制流等分析技术自动生成SIMD/向量指令的过程,以此达到提高数据并行,加快数据计算的目的。

由于其在科学计算、图像处理、机器学习数字信号处理等领域具有广泛的应用,使得业界对向量化这项技术一直有持续的关注和投入,主要是因为是自动向量化可以带来很多优势:

性能提升:自动向量化利用硬件架构提供的SIMD/Vector指令,减少了迭代循环的开销,且提高数据并行处理的能力,对计算密集或者数据规模大的场景会带来极大的性能优势。

降低编程的复杂性:开发者不需要手动编写复杂的向量化代码,交给编译器自动分析、优化和生成向量代码。

兼容性和可移植性:通过自动向量化,开发者可以编写标准的标量代码运行在不同的平台,编译器会根据目标平台特性生成可在对应平台上执行的向量代码。

810c904e-42b4-11f0-986f-92fbcf53809c.png

自动向量化实现

SpacemiT

自动向量化工具

目前LLVM框架下支持的自动向量化工具有 SLP Vectorize 和 Loop Vectorize。

SLP Vectorize(superword-level parallelism)

SLP向量化关注单次迭代间的向量化机会,在基本块中搜集相似的标量指令,通过将相似标量指令合并为向量指令的方式,来实现向量化。如下程序可以通过构造向量(a1, a2)和 (b1, b2),完成向量化算术运算。

void foo(int a1, int a2, int b1, int b2, int *A) { A[0] = a1*(a1 + b1); A[1] = a2*(a2 + b2); A[2] = a1*(a1 + b1); A[3] = a2*(a2 + b2); }

Loop Vectorize

循环向量化关注循环迭代间的向量化机会,将多次迭代处理的数据利用更宽的位宽寄存器存储,使其一次能够完成多次循环迭代的数据处理,此后每次循环迭代的下标步长将扩宽成SIMD的位宽/向量元素的位宽。

for (int i = 0; i < n; i++) { ? A[i] = B[i] + C[i] } -----> Transform for (int i = 0; i < n; i = i + step) { ? // 结合tail Folding 机制 和 Loop unroll 完成自动向量化的过程 ? for (int j = i; j < min(n, i + step); j++) { ? ? A[j] = B[j] + C[j]; ? } }

Loop Vectorize 优化介绍

循环中的标量代码是否可以向量化,主要涉及到以下三个阶段:

检查当前循环是否可以向量化,对其合法性进行校验;

在满足合法性校验的前提下,利用代价模型分析向量化的代码是否具有收益;

确定向量化代码可以带来收益,完成标量代码转换为向量代码,并更新当前循环控制流。

815520a2-42b4-11f0-986f-92fbcf53809c.png

下文会对Loop Vectorize 进行简要介绍(更多细节可以查阅文末的参考文档):

Loop Vectorize VPlan 架构介绍

VPlan 是LLVM Loop Vectorize 基础设施的重要组成部分, 其主要是为编译器在Loop Vectorize 分析中获取到的所有向量化因子(VF)进行建模和评估,根据代价模型,选择成本最优的向量化模型,并进行转换,其存储了所有可能的向量化候选者代码,使得Loop Vectorize 实现更模块化,也增强了其可扩展性,为复杂控制流和内存访问循环提供了更多向量化的机会。

整个LLVM Loop Vectorize是基于VPlan架构实现的。其在输入和输出中间加了一层VPlan层,将IR层面的转换和分析隔离,可以有效地简化数据流的分析,仅需更新VPlan IR to Output IR 的控制流信息(增加了产生向量化的代码的机会),主要有以下流程:

Input IR to VPReciple IR:通过合法性分析 + TTI 对应的目标平台后端提供的代价模型获取最优VF,并将结果存储到VPlan中,完成首次VPlan model 的构建,此时无需更新控制流。

VPlan-to-VPlan Transform Pipeline:在获取VPlan 之后,针对一些场景做优化,例如冗余Recipe 删除、简化Vector Region 实现(循环条件或者循环归纳变量的优化)和插入EVL等。

VPRecipe IR to Output IR:利用VPTransformState中提供的信息存储和吐出Output IR,生成真正的vectorizing code,此时需要重新调整循环结构并更新控制流。

816bdc34-42b4-11f0-986f-92fbcf53809c.png

Loop Vectorize 实现方式

LLVM 在Loop Vectorize 中的实现主要有以下两种方式:Vector Length Specific 和 Vector Length Agnostic 。下文会重点讲解这两个方案的优劣势并通过如下用例展示效果。

void vp_add(int *restrict a, int *restrict b, int *restrict c, int N) { for (int i = 0; i < N; i++) { ? ?a[i] = b[i] + c[i]; ?}}

Vector Length Specific (VLS)

编译器在Loop Vectorize优化阶段直接利用硬件的向量寄存器位宽进行向量化。如果当前存在尾部元素没办法填满向量寄存器,则使用标量的方式处理尾部元素。

优势:

目前,Loop Vectorize架构已经实现且无需特殊的 IR-Level Express。

劣势:

需要单独处理循环尾序。

没充分利用RVV Scalable的特性,其生成的二进制只能在指定的VLEN 架构上运行。

编译选项

clang --target=riscv64 -march=rv64imav -mllvm -riscv-v-vector-bits-min=128 -mllvm -riscv-v-vector-bits-max=128 -O3 -S xxx.c -o xxx.s

汇编效果

注:用于向量配置的 vsetivli 指令是位于向量循环 .LBB0_4 的外部。在向量循环结束后,还需要一个额外的标量循环 .LBB0_7 处理尾部元素。

8214fbca-42b4-11f0-986f-92fbcf53809c.png

Vector Length Agnostic(VLA)

最近几年,LLVM 引入了 Vector Predication IR (VP IR),其VP IR中携带的参数Mask 和 EVL(Explicit Vector Length)为独立于目标平台的各个架构提供了丰富的predicated vector instructions。当前,编译器在Loop Vectorize优化阶段的VLA 方案也是使用VP IR作为IR-Level Express完成的。编译器在循环迭代中,将所有 vector instructions 替换为predicated vector instructions,并使用EVL设置每次迭代需要处理的向量元素长度(RISC-V 架构会在后续Lowering阶段翻译成RVV vsetvli/vsetvl/vsetivli 指令)。

优势:

充分利用RVV 的Scalable 特性,其生成的二进制可以在任何VLEN架构上运行。

无需单独处理循环尾序和条件分支。

劣势:

需要特殊的 IR-Level Express(不过目前RVV VP的设计和慢慢趋于稳定,积极推进了Loop Vectorize在此方案的实现)。

所有的vector instructions都带有predicate标识,且CFG也是,这对于分支预测率比较高或者条件分支执行的概率很低的场景,可能会带来负向性能收益。

编译选项

clang --target=riscv64 -march=rv64imav -mllvm -force-tail-folding-style=data-with-evl -mllvm -prefer-predicate-over-epilogue=predicate-dont-vectorize -O3 -S xxx.c -o xxx.s

汇编效果

注:用于向量配置的 vsetvli 是位于向量循环.LBB0_2的内部,每次都会动态设置处理的元素个数,达到的效果是向量循环之后整个函数就结束了,无需再有额外的代码处理尾部元素。

82b9bac0-42b4-11f0-986f-92fbcf53809c.png

未来的重点工作方向

SpacemiT

进迭时空当前已经发布的K1芯片全面支持RISC-V Vector 1.0,其VLEN为256,后续也将推出具有更长VLEN的CPU核,进一步强化向量算力。从整个RISC-V生态考虑,灵活使用RVV相关特性,兼容程序在不同向量位宽配置的硬件上运行,将更有利于RISC-V向量算力的广泛应用。

目前,社区在积极投入基于VLA的开发实现上,进迭时空也在投入和跟踪社区向量化的开发贡献工作中。以下是Loop Vectorize优化中使能VLA比较关键的几个PATCH:

https://github.com/llvm/llvm-project/pull/76172

https://github.com/llvm/llvm-project/pull/93854

https://github.com/llvm/llvm-project/pull/90184

https://github.com/llvm/llvm-project/pull/110412

https://github.com/llvm/llvm-project/pull/108351

目前,自动向量化支持还有不少待完善的地方,基于社区最新分支,进迭时空会侧重下面的一些工作,且代码会陆续开源贡献给社区。

Loop Vectorize 优化:Recipe transform to EVLRecipe 的构建、逐步移除 Legal Cost Model,完善VPlan-based Cost Model、VPlan-to-VPlan transforms等

RISC-V 后端代价模型完善

Vector Predicate Lowering到后端的一些通用优化

结语

SpacemiT

进迭时空是一家基于新一代RISC-V架构的计算生态企业,布局高性能RISC-V CPU核、AI-CPU核、AI CPU芯片、软件系统等全栈计算技术,提供端到端的计算系统解决方案。

RISC-V是一个开源架构,其成功离不开繁荣的开源生态,秉承开源理念,我们的一些工作取自开源,也要回馈开源。进迭时空将持续投入包括编译器在内的RISC-V生态建设,融入RISC-V的全球发展,携手上下游的合作伙伴一起以RISC-V架构数智未来。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编译器
    +关注

    关注

    1

    文章

    1663

    浏览量

    50280
  • RISC-V
    +关注

    关注

    46

    文章

    2597

    浏览量

    48942
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    晶心科技推出突破性的RISC-V 27系列处理向量扩展指令处理

    晶心科技今天宣布推出AndesCore? 27系列处理核心,成为RISC-V指令集架构中领先支持向量扩展架构
    发表于 01-03 14:56 ?3240次阅读

    CPU优化技术之自动向量化实例

    SIMD 作为一种重要的并行化技术,在提升性能的同时也会增加开发的难度。目前大多数编译器都具有自动向量化的功能,将 C/C++ 代码自动替换为 SIMD 指令。
    发表于 10-08 09:31 ?2307次阅读

    关于RISC-V学习路线图推荐

    开发板,如Arduino、Raspberry Pi等,并了解其硬件配置和特性。 安装开发工具链 : 如GCC编译器RISC-V汇编和链接等,用于编写、
    发表于 11-30 15:21

    科普RISC-V生态架构(认识RISC-V)

    RISC-V 生态架构浅析前言RISC-V最近越来越多的出现在科技新闻中,大量的公司加入到RISC-V研究和生产中。在越来越多的RISC-V
    发表于 08-02 11:50

    RISC-V架构简介

    【摘要】 本文首先对RISC-V架构做了简要的介绍,在此基础上实现了LiteOS在RISC-V架构上的适配过程的具体步骤,希望对你有所帮助。1 R
    发表于 07-28 07:46

    安卓支持RISC-V架构的技术剖析

    机器CPU想匹配的代码。其过程可以用下图描述。从上图ART虚拟机的运行流程中,主要有三部分内容是移植RISC-V的关键:AOT编译器:图中.oat文件的生成工具,oat文件包含可执行二进制码的文件
    发表于 09-01 15:45

    算能重磅发布行业首款服务RISC-V CPU算丰SG2042,助力RISC-V迈向高性能计算

    和优化以及GRUB的适配和优化。王雷表示,智研院的工作填补RISC-V在服务固件领域接近空白的状态。向量化加速可以大幅提高计算性能,尤其是科学计算和数据密集型的应用,对于RISC-V
    发表于 03-03 16:45

    Arm Fortran编译器开发人员和参考指南

    提供帮助您使用Arm?编译器Linux版的Arm?Fortran编译器组件的信息。Arm?Fortran编译器是一款自动向量化的Linux用户空间Fortran
    发表于 08-10 07:11

    方舟编译器官发布对 RISC-V 后端的支持

    昨日,方舟编译器官方新发布了对 RISC-V 后端的支持。 地址:https://gitee.com/openarkcompiler-incubator/mapleall 目前,方舟编译器可以在
    的头像 发表于 11-21 10:55 ?2016次阅读

    CPU优化技术-NEON自动向量化

    SIMD 作为一种重要的并行化技术,在提升性能的同时也会增加开发的难度。目前大多数编译器都具有自动向量化的功能,将 C/C++ 代码自动替换为 SIMD 指令。
    的头像 发表于 01-11 14:53 ?1955次阅读

    开源硬件系列09期:RISC-V架构指令集与编译器技术

    进行架构探索,快速支持自定义扩展指令等,核心问题都是编译器和仿真技术。 RISC-V指令集架构 RIS
    的头像 发表于 06-28 09:05 ?1424次阅读
    开源硬件系列09期:<b class='flag-5'>RISC-V</b><b class='flag-5'>架构</b>指令集与<b class='flag-5'>编译器</b>技术

    为什么IAR编译器对开源ISA:RISC-V业务至关重要?

    为什么IAR编译器对开源ISA:RISC-V业务至关重要? 演讲ppt分享
    发表于 07-14 17:15 ?2次下载

    HighTec C/C++编译器支持Andes晶心科技RISC-V IP

    汽车编译器解决方案领先供货商HighTec EDV-Systeme GmbH宣布其针对汽车市场的高度优化C/C++编译器支持Andes晶心科技的RISC-V IP。这项支持对汽车软件开发人员来说是一
    的头像 发表于 12-12 16:26 ?1121次阅读

    HighTec C/C++编译器套件全面支持芯来RISC-V IP

    是基于LLVM开源汽车级C/C++编译器工具,已通过ISO 26262 ASIL D的安全认证。从事RISC-V架构开发的汽车软件开发者受益于这些工具来无缝支持芯来经过功能安全认证的RISC-
    的头像 发表于 12-23 09:04 ?1282次阅读
    HighTec C/C++<b class='flag-5'>编译器</b>套件全面支持芯来<b class='flag-5'>RISC-V</b> IP

    兆松科技发布高性能RISC-V编译器ZCC 4.0.0版本

    近日,兆松科技(武汉)有限公司(以下简称“兆松科技”)宣布正式发布高性能 RISC-V 编译器 ZCC 4.0.0 版本。新版本在性能优化、厂商自定义指令支持和软件库等方面实现全面升级,并同步推出
    的头像 发表于 06-27 14:48 ?1232次阅读
    兆松科技发布高性能<b class='flag-5'>RISC-V</b><b class='flag-5'>编译器</b>ZCC 4.0.0版本