|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
5 @9 p" T6 z& ?1 v6 C% ?* Z
芯片开放社区(OCC)面向开发者推出RISC-V系列内容,通过多角度、全方位解读RISC-V,系统性梳理总结相关理论知识,构建RISC-V知识图谱,促进开发者对RISC-V生态全貌的了解。本期内容将通过阐述代码密度的决定因素,带大家了解RISC-V架构代码密度的现状,并简单介绍平头哥对RISC-V代码密度的优化成果。 `( X* V/ J# \0 N$ M! x
1 X4 p) r6 V; g) v1 c8 V/ ?对于内存受限的嵌入式芯片(包括mcu和成本要求的AP类芯片)来说,代码密度非常重要。同样功能的程序,如果代码密度过大,就可能导致因ROM空间装载不下而无法使用。所以,在嵌入式领域中,代码密度是最重要的指标之一。那么,代码密度由什么决定?如何提高代码密度呢?RISC-V的代码密度现状又如何?通过本文,我们将为大家一一解答。8 Y0 P' ^' S( L7 U3 o# v% X5 u5 n
5 n0 U( ]8 K" G/ O% d5 G# Y7 @6 ?
1、代码密度的决定因素
+ ?/ S; z" H4 {* u) f8 ?9 ]& P
- H! n4 t# `) [3 d如上面的倒金字塔所示,代码密度主要由指令集、ABI、编译器、Runtime库、程序代码五个部分决定。处在金字塔的越底端,说明该因素越底层,更新的频率越小,但辐射和影响的范围却越广。% N) d7 h7 E; s% w$ {3 }
6 W4 `& T. A' C6 S0 q' t! V# F! x
2、指令集- ]' i9 m) _2 I5 G
指令集是代码密度最根本的决定性因素,它决定了一个操作在最优的情况下需要编译成多少位宽的编码。" d; g: s2 E3 D2 k
很多体系结构比如ARM、RISC-V、C-SKY都是16位指令、32位指令混编的,同样的一条指令,如果能够被编译成16位指令,那么它显然比编译成32位指令占用更小的空间;再比如,一个乘累加的操作,如果指令集中存在乘累加指令,那么它只需要一条指令来实现乘累加操作,如果没有则需要至少两条指令来完成相同的操作,假设指令都是32位的,显然一条指令将占用更少的空间。1 G2 j. E3 x/ M, m5 v) S$ E$ H, B
由于指令集的编码空间是有限的,所以指令集设计的核心是将哪些指令(包括指令操作数的范围)放到编码空间当中,就像一个商场的店面是有限的,当我们把需求最广的商家引进来时,商场的销量就会达到最高。
! N4 p' m- r& Y# S" v" E& r: _4 \% k |: O; V! O
3、ABI+ T [. }- j+ _1 @$ e9 U9 y8 Y
ABI的全称是APPlication Binary InteRFace,是二进制级别的协议,它指导着编译器如何生成代码和二进制程序,同样也指导着用户如何写汇编代码。它主要包含函数调用约定(calling convention)、数据的对齐方式等内容。
6 k* @! n2 G- w" _7 e7 C8 G其中对代码密度影响最大的就是函数调用约定,它规定了堆栈寄存器、链接寄存器、哪些寄存器需要在函数头尾保存和恢复、哪些寄存器可以作为参数寄存器等,还有一些特殊用途的寄存器。大部分特殊寄存器都是会被高频使用的,配合指令集设计可以降低代码密度;需要保存和恢复的寄存器个数同样也会影响代码密度。- D! m9 f2 y( Y8 ?% W
$ G$ V- j Y8 ?( ^5 N, @$ q
4、编译器
* P4 D Q. ~/ t1 @% H7 {5 S1 E \6 @编译器是开发者最直接接触的工具,也是给开发者体感最强的代码密度影响因素。它对代码密度的影响主要体现在两方面:
% k' E1 P3 J5 H) v3 v" R& H! h2 i① 编译器本身的优化能力,优化能力的强弱是影响编译器产品竞争力的最主要的因素。
" U2 Z5 h8 C! o② 编译器的使用方法,比如GCC,除了添加-Os之外,还可以添加-ffunction-sections -fdata-sections -Wl,--gc-sections来删除没有用到的函数。9 `3 q+ b f9 y+ R, l
, o2 B8 t$ a; m5、Runtime库8 f$ G9 [8 h6 _4 w% K
Runtime库是指程序运行所需的一些基本的函数库,它们一般都是预先编译好,和编译器一起打包发布,是工具链的一部分。由于这些函数的使用频率较高,一般程序都会用到一部分Runtime库的函数,对这些函数做针对性地优化会有比较好的收益。7 z7 ^+ P% ^: D3 O# j) L1 \
. L* B$ i; x5 p
6、程序代码
; X2 w4 p d6 k. A" I- R2 d6 \ l" {" l开发者书写的代码质量也会影响程序的代码密度,虽然编译器能够优化一部分冗余代码,但是并不能保证百分之百的优化,所以开发者也要注意代码的质量。6 E3 |- Z: S( t# V |
. b3 M. S% I8 C
7、RISC-V架构的代码密度现状
( V& w. u! r, X @! e& P: oRISC-V的代码密度表现一直被人诟病,那么,它的现状真的这么不值一提吗? v- k6 ^$ h) h: l/ }1 v
首先,RISC-V对代码密度做过一些专门的优化:. V& R8 c; K) V$ D% H. b
在指令集方面,它通过量化分析的方法测试了SPEC等benchmark,找到高频指令并将它们放到16位指令的编码当中,这就是目前的compress指令集;4 f, x, T5 ]2 ^& A) s' K
在ABI方面,rv32e通过限制16个寄存器,使代码可以生产更多的16位指令;
4 |; v1 F$ h9 _% l6 p7 B/ B6 m在编译器和Runtime中,它支持-msave-restore功能通过库函数调用的方式弥补了由于没有push/pop指令造成的一部分代码密度损失。 |
|