我有一个小程序,我试图用它来以编程方式识别CPU频率。
我的程序结构如下:
while(1)
循环中的递增寄存器SIGALRM
最初,我正在使用
register unsigned int cycles asm("r6");
...
while(1)
cycles++;
使用objdump后,我注意到这实际上转化为以下内容:
9aa0: e1a03006 mov r3, r6
9aa4: e2833001 add r3, r3, #1
9aa8: e1a06003 mov r6, r3
9aac: eafffffb b 9aa0 <estimate_from_cycles+0x1cc>
由于我不确定为什么这转换为3条指令,我尝试使用内联汇编:
register unsigned int cycles asm("r6");
...
while(1)
asm("add r6, r6, #1);
这转化为:
9aa0: e2866001 add r6, r6, #1
9aa4: eafffffd b 9aa0 <estimate_from_cycles+0x1cc>
b <label>
指令需要3个周期。但是,减去ARM上的操作,只使用1个周期。
编辑:我正在使用CodeSourcery的arm-none-linux-gnueabi-工具链而没有优化
答案 0 :(得分:0)
由于您未启用任何优化,因此很可能将实现转换为3条指令。
但是,从快速测试来看,无论如何你看起来都必须编写内联汇编,因为当我使用-O3 -fomit-frame-pointer
编译以下内容时
void test(void) {
register unsigned int cycles asm("r6");
while(1) cycles++;
}
该例程简单地优化到
00000000 <test>:
0: eafffffe b 0 <test>
即使添加volatile
也没用,因为编译器确实知道写入CPU寄存器肯定不会产生任何副作用(与内存不同),因此对它进行优化是合理的。
回答你的其他问题,
是的,当然。但我不确定这是否还需要一个周期。
作为旁注,您的逻辑不会给出非常准确的结果,因为您的过程可能会在您开始和完成测量之间切换。
你期待:
< your process >
|<---------------your alarm duration----------------->|
何时,它可能更像(其中|
是上下文切换):
<your process> | <other processes ...> | <your process>
|<---------------your alarm duration----------------->|