寻找等效于ARM DSB的RISC-V指令以基准测试内存读取耗时
RISC-V 确保加载指令完成后读取cycle寄存器的解决方案
问题分析
你当前的代码中,csrr s1, cycle(读取周期寄存器)与前面的ld指令没有数据依赖关系,CPU可能会乱序执行这条指令,导致统计的周期数没有包含所有ld指令的执行时间。fence指令仅约束内存访问操作之间的顺序,无法强制非内存指令(如CSR访问)等待前置内存操作完成,因此无法解决这个问题。
可行解决方案
方法1:通过数据依赖强制同步
利用CPU不会打破数据依赖的特性,在最后一条ld和csrr之间添加依赖所有ld结果的指令,确保所有加载操作完成后才执行周期读取。这种方法开销极小,适合性能测试场景。
修改后的代码示例:
# 记录初始周期数 csrr s0, cycle # 执行加载操作 ld t0, 0(zero) ld t1, 8(zero) ld t2, 16(zero) ld t3, 24(zero) ld t4, 32(zero) # 添加依赖指令,强制等待所有ld完成 or s2, t0, t1 or s2, s2, t2 or s2, s2, t3 or s2, s2, t4 # 记录结束周期数 csrr s1, cycle # 计算总耗时 sub s1, s1, s0
这些or指令依赖所有ld加载到t0-t4的值,CPU必须等所有ld操作完成、数据写入寄存器后,才能执行这些运算。后续的csrr指令会等待这些运算完成,从而确保统计的周期数包含所有加载操作的耗时。
注意事项
- 若担心汇编器/CPU优化掉无意义的运算指令,可以将
s2的结果写入一个不会被优化的内存地址(但会引入额外存储操作,需权衡测试精度),或者在测试环境中禁用指令优化。
为什么fence无法解决问题
RISC-V的fence指令仅对内存访问操作(加载/存储)的顺序进行约束,而csrr是CSR寄存器访问指令,不属于内存操作范畴。因此即使在最后一条ld后添加fence,CPU仍可能提前执行csrr,无法保证所有加载操作完成。
内容的提问来源于stack exchange,提问作者SFV
相关产品推荐
相关产品推荐

