X86 rdtsc&x27;在Atom N450上,s的返回值为always_uMod10==0
在我的E8200设备上不会出现这种情况,但在我的Atom N450上网本(都运行OpenSuse 11.2)上,每当我读取CPU的TSC时,返回值为X86 rdtsc&x27;在Atom N450上,s的返回值为always_uMod10==0,x86,x86-64,systems-programming,rdtsc,intel-atom,X86,X86 64,Systems Programming,Rdtsc,Intel Atom,在我的E8200设备上不会出现这种情况,但在我的Atom N450上网本(都运行OpenSuse 11.2)上,每当我读取CPU的TSC时,返回值为mod 10==0,即。E它没有余数可以被10整除。我使用RDTSC值来测量有趣的代码片段所花费的时间,但为了演示,我编写了这个小程序: .text .global _start _start: xorl %ebx,%ebx xorl %ecx,%ecx xorl %
mod 10==0
,即。E它没有余数可以被10整除。我使用RDTSC值来测量有趣的代码片段所花费的时间,但为了演示,我编写了这个小程序:
.text
.global _start
_start: xorl %ebx,%ebx
xorl %ecx,%ecx
xorl %r14d,%r14d
movb $10,%cl
loop: xchgq %rcx,%r15 # save to reg
cpuid
rdtsc
shlq $32,%rdx
xorq %rax,%rdx # full 64 bit of RDTSC
movq %r14,%r13 # save the old value
movq %rdx,%r14 # copy current
movq %r14,%rsi # argv[1] of printf()
subq %r13,%rdx # argv[2] (delta)
leaq format(%rip),%rdi # argv[0]
xorl %eax,%eax # no stack varargs
call printf
xchgq %rcx,%r15
loop loop
0: xorl %eax,%eax
movb $0x3c,%al
syscall
.size _start, .-_start
.data
format: .asciz "rdtsc: %#018llx = %1$llu -- delta: %llu\n"
(我通常使用自己的例程进行转换,但为了防止读者暗示可能存在错误,我在这里只使用printf()
使用上述代码,输出为(例如):
很容易看出,三角洲的变化量是合理的。但值得注意的是(更不用说共谋了;-)最低有效十进制数字总是0
我观察这种现象已经两年多了,堆栈溢出并不是我第一次公开这个问题。但我还没有得到一个合理的答案。我们(我和其他人)想出的想法是什么
- TSC仅每10个周期增加一次,但随后增加10,或
- TSC在内部正确更新,但仅每10个周期向外部反映一次,或
- TSC每循环递增10
rdtsc.s
):
为了使用gcc前端构建它,i。e
gcc -l c rdtsc.s -o rdtsc
您必须添加(或用main:
标签替换\u start:
标签)并使其成为全局标签
[更新(2012-09-15~21:15 UTC):事实上,我以前也可以这样做:我只是让它在
睡眠(1)
之前和之后获取TSC,它给出的增量略大于1666000000,这表明上面列表中的第三点是错误的。但我仍然不知道为什么我不能获得完整的精度。/update]软件开发手册第3B卷中说:
。。。对于Intel Atom处理器。。。时间戳计数器以恒定速率递增。
该速率可由处理器的最大核心时钟与总线时钟之比设置
或者可以由处理器启动时的最大解析频率设置。这个
最大分辨频率可能不同于设备的最大合格频率
处理器
这并不能完全回答为什么你会看到10的具体步骤,但确实如此
指出一个特定的实现可以自由地增加1以外的值。
我想你得仔细看看你的电脑的具体硬件规格
计算机和BIOS实现,以发现为什么正好是10。您的计算机的BIOS不支持CPU 所以你要在恒定的比率下跑步
这个比率不能不同,因为您的时钟频率比率是10。我猜我的错是,假设您使用的Atom N450名称是处理器,而不是笔记本电脑型号。。。我不完全确定BIOS对TSC没有影响,因为它处理初始化各种芯片组/时钟等的某些方面。不过,在启动后,我可以看到它不应该再影响TSC。不过,我远不是BIOS的专家。。。
as rdtsc.s -o rdtsc.o
ld --dynamic-linker=/lib64/ld-linux-x86-64.so.2 rdtsc.o -L /lib64 -l c -o rdtsc
gcc -l c rdtsc.s -o rdtsc