查看: 1329|回复: 0
收起左侧

RISC-V生态全景解析(三):一文看懂RISC-V代码密度

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-5-3 19:46:48 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-8-27 20:20 编辑

    对于内存受限的嵌入式芯片(包括MCU和成本要求的AP类芯片)来说,代码密度非常重要。同样功能的程序,如果代码密度过大,就可能导致因ROM空间装载不下而无法使用。所在,在嵌入式领域中,代码密度是最重要的指标之一。那么,代码密度由什么决定?如何提高代码密度呢?RISC-V的代码密度现状又如何?


    一、代码密度的决定因素

    平头哥 玄铁910-907-RISC-V生态全景解析(三):一文看懂RISC-V代码密度risc-v单片机中文社区(1)

    如上面的倒金字塔所示,代码密度主要由指令集、ABI、编译器、Runtime库、程序代码五个部分决定。处在金字塔的越底端,说明该因素的越底层,更新的频率越小,但辐射和影响的范围却越广。


    二、指令集

    指令集是代码密度最根本的决定性因素,它决定了一个操作在最优的情况下需要编译成多少位宽的编码。

    很多体系结构比如ARM、RISC-V、C-SKY都是16位指令、32位指令混编的,同样的一条指令,如果能够被编译成16位指令,那么它显然比编译成32位指令占用更小的空间;

    再比如,一个乘累加的操作,如果指令集中存在乘累加指令,那么它只需要一条指令来实现乘累加操作,如果没有则需要至少两条指令来完成相同的操作,假设指令都是32位的,显然一条指令将占用更少的空间。

    由于指令集的编码空间是有限的,所以指令集设计的核心是将哪些指令(包括指令操作数的范围)放到编码空间当中,就像一个商场的店面是有限的,当我们把需求最广的商家引进来时,商场的销量就会达到最高。


    三、ABI

    ABI的全称是Application Binary Interface,是二进制级别的协议,它指导着编译器如何生成代码和二进制程序,同样也指导着用户如何写汇编代码。它主要包含函数调用约定(calling convention)、数据的对齐方式等内容。

    其中对代码密度影响最大的就是函数调用约定,它规定了堆栈寄存器、链接寄存器、哪些寄存器寄存器需要在函数头尾保存和恢复、哪些寄存器可以作为参数寄存器等,还有一些特殊用途的寄存器。

    大部分特殊寄存器都是会被高频使用的,配合指令集设计可以降低代码密度;

    需要保存和恢复的寄存器个数同样也会影响代码密度。


    四、编译器

    编译器是开发者最直接接触的工具,也是给开发者体感最强的代码密度影响因素。它对代码密度的影响主要体现在两方面:

    编译器本身的优化能力,优化能力的强弱是影响编译器产品竞争力的最主要的因素。

    编译器的使用方法,比如GCC,除了添加-Os之外,还可以添加-ffunction-sections -fdata-sections -Wl,--gc-sections来删除没有用到的函数。


    五、Runtime库

    Runtime库是指程序运行所需的一些基本的函数库,它们一般都是预先编译好,和编译器一起打包发布,是工具链的一部分。

    由于这些函数的使用频率较高,一般程序都会用到一部分Runtime库的函数,对这些函数做针对性地优化会有比较好的收益。


    六、程序代码

    开发者书写的代码质量也会影响程序的代码密度,虽然编译器能够优化一部分冗余代码,但是并不能保证百分之百的优化,所以开发者也要注意代码的质量。


    七、RISC-V架构的代码密度现状

    RISC-V的代码密度表现一直被人诟病,那么,它的现状真的这么不值一提吗?

    首先,RISC-V对代码密度做过一些专门的优化。在指令集方面,它通过量化分析的方法测试了spec等benchmark,找到高频指令并将它们放到16位指令的编码当中,这就是目前的compress指令集;

    在ABI方面,rv32e通过限制16个寄存器,使代码可以生产更多的16位指令;

    在编译器和Runtime中,它支持-msave-restore功能通过库函数调用的方式弥补了由于没有push/pop指令造成的一部分代码密度损失。

    这里需要特别指出的是,RISC-V的链接器做了较多的relax优化,即某些指令的目标符号距离比较接近的时候,可以优化使用更少的指令。

    比如函数跳转,比如具体在4k之内,可以使用一条jalr指令实现,而如果超过4k的话,则需要auipc+jalr或者lui+jalr两条指令实现。

    一般在未链接的object文件中,预留的都是指令条数最多的形式,链接之后很大一部分将被优化。

    如果测试的benchmark如果统计的是object文件,比如CSiBE,那么结果会比实际的要差一些。

    那么,在做了这些优化之后,为什么RISC-V的代码密度还是被这么多人诟病呢?

    主要是由于compress指令集设计时,基于的benchmark是spec2006,它在应用PC端非常具有代表性,但在嵌入式领域却不具有典型性。

    所以在RISC-V 64位核中,它的代码密度表现还不错,但是在真正关心代码密度的嵌入式领域表现却不尽如人意。

    其次,ABI也需要重新针对嵌入式领域做量化评估和设计。


    八、平头哥对RISC-V的代码密度优化

    针对代码密度,RISC-V社区目前也在不断地优化中,比如code-size TG和EABI TG的成立。

    平头哥也参与其中,在优化代码密度的道路上不断前行。目前,平头哥所做的优化有如下两个方面:


    九、Runtime库

    平头哥设计开发了一套针对嵌入式领域的、最大化优化代码密度的Lower-Level Runtime Library。


    目前玄铁E902、玄铁E906和玄铁E907均已支持该Runtime库,它相对于libgcc提升40%;


    相对于Arm的macrolib,玄铁E902与M0-plus相当,玄铁E906、玄铁E907与M4相当。


    十、ABI

    目前,社区正在设计、制定针对嵌入式领域的新的ABI——EABI(Embedded ABI),它不仅会调整Calling Convention以减少中断延迟,也会考虑代码密度,使用量化分析地方法设计出一套对嵌入式领域优化的ABI。平头哥作为EABI Task Group的Co-Chair,也参与其中推动EABI的前进。

    作为平头哥玄铁系列科普文章之一,以上是本文关于RISC-V代码密度的介绍及平头哥在其中的优化成果的简介,更多关于RISC-V指令集优劣势分析等内容可参见后续文章。







    上一篇:玄铁芯片RISC-V指令架构
    下一篇:Perf-V与运行平头哥Wujian100平台
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-3-29 23:31 , Processed in 0.695958 second(s), 48 queries .

    快速回复 返回顶部 返回列表