1、压缩指令集介绍
- RISC-V的压缩指令集(C扩展)是一种设计用于减少代码大小和提高性能的技术。标准的RISC-V指令是32位,压缩指令集可以将部分32位的指令用16位的指令替代,从未减小程序占用存储空间的大小,提高指令密度,也可以提高指令缓存的命中率本
- 优势:
- 高指令密度: 相同的存储空间可以存储更多的指令,从而提高代码的紧凑性和执行效率
- 低功耗:由于指令的紧凑性,处理器在执行这些指令时需要更少的能量,这对于嵌入式设置来说是一个显著的优势
- 劣势:
- 性能可能受限:在某些高性能场景中,性能不如传统的非压缩指令集。这是因为压缩指令集可能牺牲了一些执行速度和灵活性来换取更高的密度和效率
- 兼容性问题:由于RISC-V架构是相对较新的架构,其压缩指令集在现有的软件和工具链中的支持可能不如传统的非压缩指令集完善。
2、识别压缩指令集和非压缩指令集
2.1、源文件
#include <stdio.h>
int main(void)
{
int temp = 1;
printf("temp=%d\n", temp);
return 0;
}
2.2、使用压缩指令集
- 编译命令:
- riscv64-unknown-elf-gcc test.c -mabi=lp64d -march=rv64imadc
- 反汇编命令:
- 反汇编命令:riscv64-unknown-elf-objdump -dS ./a.out > test_c.dis
- 压缩指令集的指令长度是2Byte,非压缩指令集的指令长度是4Byte
- 不是所有的指令都可以用压缩指令集替代,编译器在编译时会判断哪些指令能用压缩指令集哪些不能用,所以使用压缩指令集并不是所有的指令都会变成压缩指令集
2.3、不使用压缩指令集
00000000000101a4 <main>:
101a4: fe010113 addi sp,sp,-32
101a8: 00113c23 sd ra,24(sp)
101ac: 00813823 sd s0,16(sp)
101b0: 02010413 addi s0,sp,32
101b4: 00100793 li a5,1
101b8: fef42623 sw a5,-20(s0)
101bc: fec42783 lw a5,-20(s0)
101c0: 00078593 mv a1,a5
101c4: 0001c7b7 lui a5,0x1c
101c8: 67078513 addi a0,a5,1648 # 1c670 <__clzdi2+0x3a>
101cc: 152000ef jal ra,1031e <printf>
101d0: 00000793 li a5,0
101d4: 00078513 mv a0,a5
101d8: 01813083 ld ra,24(sp)
101dc: 01013403 ld s0,16(sp)
101e0: 02010113 addi sp,sp,32
101e4: 00008067 ret
- 编译命令:
- riscv64-unknown-elf-gcc test.c -mabi=lp64d -march=rv64imad
- 反汇编命令:
- riscv64-unknown-elf-objdump -dS ./a.out > test.dis
- 所有的指令都是非压缩指令,指令长度都是4Byte
2.4、压缩指令集和非压缩指令集的区别
- 压缩指令集的指令长度是2Byte,非压缩指令集的指令长度是4Byte
- 压缩指令集的指令长度比较短,但是功能受限,不是所有的非压缩指令都可以用压缩指令替代,具体哪些可以替代编译器会判断
- 压缩指令集只有16bit来表示信息,非压缩指令有32bit来表示信息,所以压缩指令集的功能是受限的,压缩指令集可以理解成裁剪版的非压缩指令集 (比如跳转指令,非压缩的跳转指令的跳转范围就要比压缩的跳转指令范围更大)
3、使用压缩指令集
- 在编译时指定要使用压缩指令集:-march=rv64imadc
- march:是在编译时指定架构和支持的指令集
- rv64:表示RISC-V架构的64位CPU
- imadc:是表示CPU支持的指令集,每个字母代表一种指令集,其中
c就是压缩指令集
- 选择压缩指令集后,在编译时,编译器会自动判断,将能用压缩指令替换非压缩指令的地方都替换成压缩指令,这个过程,程序员不需要感知
- 在内嵌汇编中使用压缩指令(编译参数-march必须添加c指令集):
- 内嵌汇编可以参考博客:《RISC-V架构学习——C语言内嵌汇编总结》
- 每个指令都有压缩版本和非压缩版本,比如add指令
- add:非压缩版本
- c.add:添加前缀c表示使用压缩版本
- 内嵌汇编里直接使用压缩指令,在编译时可能会报错,因为压缩版本的指令是有很多限制的,不是所有的地方都可以使用压缩指令,不如果不是对指令集细节特别清楚,不建议在内嵌汇编里使用压缩指令