本文是纯干货。
由于现代的处理器支持乱序执行代码,另一个说法叫做cpu指令重拍。为了测量的准确性,本例中使用了cpuid指令,属于序列化指令。它可以保证汇编指令的执行的有序性。用来避免cpu指令重拍。
注意,这里说的是cpuid汇编指令,不是java和c中的volatile关键字,更不是什么内存屏障。
这个问题可以参考文章https://stackoverflow.com/questions/12631856/difference-between-rdtscp-rdtsc-memory-and-cpuid-rdtsc
这里的循环次数的设置在cpuid指令之后,因为cpuid指令会修改rcx寄存器的值。
tsc寄存器在每个cpu时钟信号到来时+1。比如,主频为 1M Hz 的 CPU,这个寄存器每秒就递增 1 000 000 次。服务器 x86-64 的 CPU 主频一般都在 1G Hz 以上,所以通过这个指令,我们可以获得纳秒级别的时间精度。
本文汇编代码是在linux 64位cpu x86-64架构下编写的。
现在直接上代码。
;test.asm
extern printf
section .data
fmt0 db "test speed",10,0
fmt4 db 10,"number of loops: %d",10,0
fmt5 db "A: %d",10,0
fmt6