gpt4 book ai didi

x86 - 在 Atom N450 上,rdtsc 的返回值是 _always_ mod 10 == 0

转载 作者:行者123 更新时间:2023-12-04 20:49:33 25 4
gpt4 key购买 nike

在我的 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 %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()。)

使用上面的代码,输出是(例如):
rdtsc: 0x000b88ef933ffd06 = 3246787292822790 -- delta: 3246787292822790
rdtsc: 0x000b88ef9342fcf4 = 3246787293019380 -- delta: 196590
rdtsc: 0x000b88ef93435dca = 3246787293044170 -- delta: 24790
rdtsc: 0x000b88ef9343b43c = 3246787293066300 -- delta: 22130
rdtsc: 0x000b88ef93440c34 = 3246787293088820 -- delta: 22520
rdtsc: 0x000b88ef9344604e = 3246787293110350 -- delta: 21530
rdtsc: 0x000b88ef9344b4d6 = 3246787293131990 -- delta: 21640
rdtsc: 0x000b88ef9345085a = 3246787293153370 -- delta: 21380
rdtsc: 0x000b88ef93455d96 = 3246787293175190 -- delta: 21820
rdtsc: 0x000b88ef9345b16a = 3246787293196650 -- delta: 21460

很容易看出,增量在合理的范围内变化。但引人注目的(不是说阴谋;-)是最低有效十进制数字始终为 0。

我观察这种现象已经两年多了,Stack Overflow 并不是我第一个公开这个问题的地址。但我还没有得到合理的答案。我们(我和其他人)提出的想法是
  • TSC 仅每 10 个周期增加一次,然后增加 10,或
  • TSC 在内部正确更新,但仅每 10 个周期反射(reflect)到外部,或
  • TSC 每个周期增加 10。

  • 然而,这些观点都没有真正意义。我实际上应该在 E8200 上运行一个类似的程序(目前是乱序的),以查看增量的数量级是否与上述输出中的数量级相同或仅为十分之一。 (有志愿者吗?)

    谷歌搜索没有帮助,英特尔的手册也没有。

    在与其他人讨论时,没有其他人经历过同样的行为。如果它与内核有关,那么至少有 3 个版本受到影响,但是……内核与它有什么关系?

    我也使用过上网本,它带着新的主板回来了——这意味着一个新的 CPU,所以 N450 的至少两个独立实体必须受到影响。

    我还针对时钟频率变化采取了措施(无论我将时钟固定到什么频率,这些值仅在预期范围内变化(与所示相同)),并关闭了 HT,尽管这些实际上应该有助于获得其他一些最低有效数字,而不是阻止它们。但只是为了确定。

    好吧,如果有人想在他们的机器上运行该程序,命令行是(假设您将源代码保存在文件 rdtsc.s 中):
    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 前端构建它,我。 e.
    gcc -l c rdtsc.s -o rdtsc

    您必须添加(或替换 _start: 标签) main:标记并使其全局化。

    [更新(2012-09-15 ~21:15 UTC):其实我之前也可以这样做:我只是让它在 sleep(1)之前和之后使用TSC ,这给出了略大于 1,666,000,000 的 delta,这表明上面列表中的第三点是错误的。但我仍然不知道为什么我没有得到完全的精度。/更新]

    最佳答案

    软件开发手册的第 3B 卷是这样说的:

    ... for Intel Atom processors ... the time-stamp counter increments at a constant rate. That rate may be set by the maximum core-clock to bus-clock ratio of the processor or may be set by the maximum resolved frequency at which the processor is booted. The maximum resolved frequency may differ from the maximum qualified frequency of the processor, ...



    这并不能完全回答为什么您会看到特定的 10 步,但确实如此
    指出特定实现可以自由增加 1 以外的其他值。
    我怀疑您必须仔细查看您的特定硬件规范
    机器和 BIOS 实现以发现为什么它正好是 10。

    关于x86 - 在 Atom N450 上,rdtsc 的返回值是 _always_ mod 10 == 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12394131/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com