do_loop: addi.d rj, rj, -1
bnez rj, do_loop
现代CPU 对于上面汇编段,每个时钟周期都将寄存器rj 减一。
也就是说,如果将rj 初始化为时钟频率大小,则这段代码执行时间为1秒。
以龙芯3C5000 2.2GHz 处理器为例,如果将rj 初始化为(10*2.2×10^9),这段代码执行需要10秒,
结果也是如此,我们使用龙芯stable counter(100MHz,类似于Intel TSC)进行计时,计数器正好过了 1,000,000,014 次计数,约为10.00000014 秒。
rj 寄存器初始值 stable counter 计数 通过rj 估计的运行时间
10*2.2×10^9 1,000,000,014 10s
100*2.2×10^9 10,000,000,032 100s
1000*2.2×10^9 100,000,000,020 1000s
可见,这样方法稳定性很好(误差没有随着时间增大增大),
原因是这段测试代码非常简单,没有访存和共享资源的竞争,
因此常被反过来用寄存器计数和运行时间大致确定CPU 的频率(前提CPU不是变频的)。
我有个疑问是,既然这段代码没有访存,看似也有没有竞争,为什么会受到其他CPU 核心负载的影响。
也就是说,上面测试结果都是在其他CPU 空闲情况下执行的,如果其他CPU 有负载,执行时间会更长(即用于时间计数的stable counter 会增大)。
--
修改:lambdago FROM 111.183.24.*
FROM 111.183.24.*