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