English 中文(简体)
计算CPU频率,RDTSC总回报为0
原标题:Calculating CPU frequency in C with RDTSC always returns 0

我们的教员向我们提供了以下法典,这样我们就可以衡量一些算法的业绩:

#include <stdio.h>
#include <unistd.h>

static unsigned cyc_hi = 0, cyc_lo = 0;

static void access_counter(unsigned *hi, unsigned *lo) {
    asm("rdtsc; movl %%edx,%0; movl %%eax,%1"
    : "=r" (*hi), "=r" (*lo)
    : /* No input */
    : "%edx", "%eax");
}

void start_counter() {
    access_counter(&cyc_hi, &cyc_lo);
}

double get_counter() {
    unsigned ncyc_hi, ncyc_lo, hi, lo, borrow;
    double result;

    access_counter(&ncyc_hi, &ncyc_lo);

    lo = ncyc_lo - cyc_lo;
    borrow = lo > ncyc_lo;
    hi = ncyc_hi - cyc_hi - borrow;

    result = (double) hi * (1 << 30) * 4 + lo;

    return result;
}

然而,我需要该守则能够携带到具有不同邮联频率的机器。 为此,我试图计算该编码所运行的机体的频率:

int main(void)
{
    double c1, c2;

    start_counter();

    c1 = get_counter();
    sleep(1);
    c2 = get_counter();

    printf("CPU Frequency: %.1f MHz
", (c2-c1)/1E6);
    printf("CPU Frequency: %.1f GHz
", (c2-c1)/1E9);

    return 0;
}

问题是,结果总是零,我无法理解原因。 I mît(Arch)作为国际电离层光器的客人。

在一个朋友的机器(MacBook)上,它在某种程度上发挥了作用;我说,结果大于0,但因CPU的频率没有固定(我们试图固定,但出于某种原因,我们无法这样做)。 他拥有一台不同的机器,作为东道方,运行Lino(Ubuntu),还报告。 0. 这些规则排除了虚拟机器上的问题,我认为这是第一个问题。

为什么会发生这种情况,我如何确定?

最佳回答

由于其他答案是有用的,我试图更详细地解释。 问题是,一个现代的万国邮联能够执行命令。 你们的法典始于:

rdtsc
push 1
call sleep
rdtsc

现代万国邮联确实在而不是上执行指示。 尽管你有原来的命令,但万国邮联(主要是)可以自由执行。

rdtsc
rdtsc
push 1
call sleep

在这种情况下,它清楚地说明为什么两个<代码>rdtsc之间的区别(至少非常接近) 0. 为了防止这种情况,你需要执行一项指示,即万国邮联将never 重新安排执行命令。 这方面使用的最常见指示是<编码>CPUID。 与此相关的另一个答案是(如果记忆发挥作用),从那里开始,如何正确/有效地利用<编码>CPUID。

当然,Tim Post是正确的,你也看到了虚拟机器造成的问题。 然而,正如现在的情况一样,没有保证你的代码将正确操作,甚至使用真正的硬件。

内容提要:为什么守则would work:首先,指令can/em> 其次,有可能(至少部分执行)<条码/代码>载有防止<条码>的序列指示。 从重新排列,而其他则不提(或可能包含这些内容),而只是在特定(但未说明)情况下执行。

你们留下的东西是几乎可以改变的行为,几乎可以重新归结,甚至只是从一到二。 它可以在一段时期内产生极其准确的结果,而某些(几乎)原因完全无法解释(例如,某些其他进程完全发生的情况)。

问题回答

我可以不谈一下与你的法典究竟有什么错误,但你为这种简单指示做了大量不必要的工作。 我建议您简化<条码>。 基本法典。 你们不需要用64美分的数学来做自己的事,你也不需要把这一行动的结果翻一番。 您无需在您的网上使用单独的产出,你可以告诉海湾合作委员会使用轴心和代子。

本条非常简化:

#include <stdint.h>

uint64_t rdtsc() {
    uint64_t ret;

# if __WORDSIZE == 64
    asm ("rdtsc; shl $32, %%rdx; or %%rdx, %%rax;"
        : "=A"(ret)
        : /* no input */
        : "%edx"
    );
#else
    asm ("rdtsc" 
        : "=A"(ret)
    );
#endif
    return ret;
}

你们还应考虑删除你重新获得的价值观,以便你能够看到你是否重新获得零,或者其他东西。

hmmm I m 不是正面的,但我怀疑这个问题可能在此线内:

结果 = (双重) hi * (1 << 30) * 4 + lo;

如果你能够安全地在“未签署协议”中进行如此巨大的重复,我会怀疑。 难道不是经常是32倍的数字? ......认为你可以安全地乘2^32,必须把它作为2^30的外加“* 4”这一事实,最终已经暗示了这种可能性。 ......你可能需要将每一次子对手转换成两倍(而不是一对一对一对一),并且用两倍的重复进行。





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...