RISC-V压缩指令扩展测试

发布于:2024-05-24 ⋅ 阅读:(52) ⋅ 点赞:(0)

概述

RISC-V定义了压缩指令扩展(compressed instruction-set extension ),命名为“C”扩展。压缩指令使用16位宽指令替换32位宽指令,从而减少代码量。这个C扩展可运用在RV32、RV64和RV128指令集上,通常使用“RVC”来表示支持该扩展指令集。一个程序通常有50%的指令可以使用RVC指令替代,可以减少25%~30%的代码量。

RISC-V还定义了另外一组压缩指令扩展“Zc*”,扩展现有的C扩展,并新增了一些16位扩展,包括Zca、Zcd、Zcf和Zcb、Zcmp、Zcmt。

RISC-V定义了B扩展(bit-manipulation extension),用于位操作,包括Zba、Zbb和Zbs。B扩展可以减少代码量,提升性能和降低功耗。

CSiBE

CSiBE是用于代码大小测试的benchmark。

环境准备

下载CSiBE,如下:

$ git clone https://github.com/szeged/csibe.git

工具链下载芯来的Nuclei RISC-V Toolchain,这里下载2024.02版本,下载完成解压即可。

编译

CSiBE是采用cmake的方式进行构建的,cmake文件在toolchain-files目录,我们参考已有的模板编写,命名为gcc-risc-v.cmake,内容如下:

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR RISCV32)

set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)

set(CMAKE_C_COMPILER /toolchain/gcc/bin/riscv64-unknown-elf-gcc)
set(CMAKE_CXX_COMPILER /toolchain/gcc/bin/riscv64-unknown-elf-g++)

# 1. 无c和b扩展
set(RISCV_FLAGS "-Os -march=rv32imaf -mabi=ilp32f -D__GLIBC_HAVE_LONG_LONG")
# 2. 基础c扩展
# set(RISCV_FLAGS "-Os -march=rv32imafc -mabi=ilp32f -D__GLIBC_HAVE_LONG_LONG")
# 3. zc和b扩展
# set(RISCV_FLAGS "-Os -march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs -mabi=ilp32f -D__GLIBC_HAVE_LONG_LONG")
# 4. zc、b和芯来Xxlcz扩展
# set(RISCV_FLAGS "-Os -march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxlcz -mabi=ilp32f -D__GLIBC_HAVE_LONG_LONG")
set(CMAKE_C_FLAGS "${RISCV_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${RISCV_FLAGS}" CACHE STRING "" FORCE)
  • CMAKE_C_COMPILER和CMAKE_C_COMPILER:配置risc-v的c和c++编译器
  • RISCV_FLAGS:指定-march参数,这里测试c和b扩展、基础c扩展以及zc和b扩展三种情况

在顶级目录新建一个build目录,编译如下:

$ ./csibe.py --build-dir=build/ --toolchain gcc-risc-v CSiBE-v2.1.1
  • build-dir:指定编译目录
  • toolchain:制定工具链文件,即上面的gcc-risc-v.cmake

编译的结果在build目录下。

CSiBE

结果分析

CSiBE的测试结果列出所有的程序文件编译大小,这里我们采用所有文件的平均值进行对比。

选项 扩展 代码量均值 对比
rv32imaf 无压缩扩展 4370 100%
rv32imafc 基础c扩展 3571 82%
rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs zc新扩展+b扩展 3358 76.9%
rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxlcz zc新扩展+b扩展+芯来Xxlcz扩展 3349 76.6%

可以看出,采用基础c扩展代码量量缩减18%,而采用zc新扩展和b扩展缩减23%。

Embench-IoT

Embench-IoT是嵌入式的性能测试工具,嵌入式系统的特点是:没有OS,最小C库支持,没有输出流。Embench-IoT运行结束后会打印19个测试程序的尺寸大小,类似如下:

Benchmark            size
---------            ----
aha-mont64          1,388
crc32                 588
cubic              35,018
edn                 1,870
huffbench           5,958
matmult-int         1,040
md5sum              5,168
minver              4,332
nbody               8,868
nettle-aes          2,874
nettle-sha256       4,358
nsichneu           16,292
picojpeg            7,774
primecount            624
qrduino            10,044
sglib-combined      6,784
slre                2,646
st                  8,930
statemate           3,958
tarfind             4,752
ud                  3,336
wikisort           12,576
---------           -----
Geometric mean      4,292
Geometric SD            2.72
Geometric range  10,072.17910752827
All benchmarks sized successfully

环境准备

下载Embench-IoT,如下:

$ git clone https://github.com/embench/embench-iot.git

工具链下载芯来的Nuclei RISC-V Toolchain,这里下载2024.02版本,下载完成解压即可。

另外需要安装python3.6或以后版本,还需要python包pyelftools:

$ pip3 install pyelftools

编译

Embench-IoT使用build_all.py脚本编译,编译完成后使用benchmark_size.py脚本查看代码大小,还可以使用benchmark_speed.py脚本测试速度性能。

无压缩

$ ./build_all.py --clean --arch riscv32 --chip generic --board ri5cyverilator --cc /toolchains/gcc/bin/riscv64-unknown-elf-gcc '--cflags=-c -Os -march=rv32imaf -mabi=ilp32f -ffunction-sections' '--ldflags=-march=rv32imafc -mabi=ilp32f -specs=nosys.specs -specs=nano.specs -Wl,-gc-sections' --user-libs=-lm --dummy-libs=
$ ./benchmark_size.py --absolute
Geometric mean      5,595
Geometric SD            2.60
Geometric range  12,379.939559115413
All benchmarks sized successfully

基础C扩展

$ ./build_all.py --clean --arch riscv32 --chip generic --board ri5cyverilator --cc /toolchains/gcc/bin/riscv64-unknown-elf-gcc '--cflags=-c -Os -march=rv32imafc -mabi=ilp32f -ffunction-sections' '--ldflags=-march=rv32imafc -mabi=ilp32f -specs=nosys.specs -specs=nano.specs -Wl,-gc-sections' --user-libs=-lm --dummy-libs=
$ ./benchmark_size.py --absolute
Geometric mean      4,795
Geometric SD            2.70
Geometric range  11,148.051624219981
All benchmarks sized successfully

Zc和B扩展

$ ./build_all.py --clean --arch riscv32 --chip generic --board ri5cyverilator --cc /toolchains/gcc/bin/riscv64-unknown-elf-gcc '--cflags=-c -Os -march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs -mabi=ilp32f -ffunction-sections' '--ldflags=-march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs -mabi=ilp32f -mabi=ilp32f -specs=nosys.specs -specs=nano.specs -Wl,-gc-sections' --user-libs=-lm --dummy-libs=
$ ./benchmark_size.py --absolute
Geometric mean      4,301
Geometric SD            2.72
Geometric range  10,099.132824302542
All benchmarks sized successfully

Zc、B和Xxlcz扩展

$ ./build_all.py --clean --arch riscv32 --chip generic --board ri5cyverilator --cc /toolchains/gcc/bin/riscv64-unknown-elf-gcc '--cflags=-c -Os -march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxlcz -mabi=ilp32f -ffunction-sections' '--ldflags=-march=rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxlcz -mabi=ilp32f -mabi=ilp32f -specs=nosys.specs -specs=nano.specs -Wl,-gc-sections' --user-libs=-lm --dummy-libs=
$ ./benchmark_size.py --absolute
Geometric mean      4,290
Geometric SD            2.72
Geometric range  10,069.520004018736
All benchmarks sized successfully

结果分析

Embench-IoT的测试结果会打印输出代码量的几何平均值、方差等,这里我们采用几何平均值进行对比。

选项 扩展 代码量均值 对比
rv32imaf 无压缩扩展 5595 100%
rv32imafc 基础c扩展 4795 86%
rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs zc新扩展+b扩展 4301 76.9%
rv32imaf_zca_zcb_zcf_zcmp_zcmt_zba_zbb_zbc_zbs_xxlcz zc新扩展+b扩展+芯来自研的代码缩减Xxlcz扩展 4290 76.7%

可以看出,采用基础c扩展代码量量缩减14%,而采用zc新扩展和b扩展缩减33%。

参考

  1. RISC-V C扩展和Zce扩展Code Size实测
  2. Embench的介绍和在RISCV32模拟器上的运行
  3. nuclei sdk documentation

欢迎关注“安全有理”微信公众号。

安全有理