5

我正在尝试通过 Linux 内核模块以非常高的精度测量 Linux 内核中的某些代码所花费的时间。

为此,我尝试了 rdtscl(),它给出了代码中使用的时钟滴答数,如下所示:

unsigned long ini, end;
rdtscl(ini);
//some code...
rdtscl(end);
printk("time taken=%lu ticks",end-ini);

正如我所提到的那样,http ://en.wikipedia.org/wiki/Time_Stamp_Counter说TSC 是自 Pentium 以来所有 x86 处理器上都存在的 64 位寄存器。那么,如果我有双核处理器,这个计数器会出现在两个内核中,还是只有一个,因为它只有一个处理器但双核?

第二个问题是:我有 Intel Xeon i3 处理器,它有 4 个处理器,每个处理器有 2 个内核。然后,测量时钟滴答声,将给出单个处理器的滴答声还是所有 4 个处理器的加法?

4

4 回答 4

4

如果您没有时钟滴答,那么您的代码有严重问题。你是自己写的rdtscl[或从不是一个好的来源的地方复制它?]

顺便说一句,现代英特尔(和 AMD)处理器很可能具有“恒定 TSC”,因此停止、睡眠、运行速度较慢等的处理器仍会以与其他处理器相同的速度滴答作响 - 它可能不在仍然同步,但这是另一回事。

尝试只运行一个从计数器打印值的循环 - 只是 RDTSC 指令本身应该需要大约 30-50 个时钟周期,所以你应该看到它在移动。

编辑:这是我的 rdtsc 函数:

void rdtscl(unsigned long long *ll)
{
    unsigned int lo, hi;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));                        
    *ll = ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );  
}

或者,作为返回值的函数:

unsigned long long rdtscl(void)
{
    unsigned int lo, hi;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));                        
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );  
}

我注意到您的代码没有传递 unsigned long 的指针,这让我怀疑您实际上并没有将时间戳计数器传递回调用者,而是只是保留它碰巧具有的任何值 - 这很可能是两个值相同。

于 2012-12-24T08:52:40.370 回答
2

同一篇WikiPedia文章确实提到了 TSC 的问题,如下所示,

With the advent of multi-core/hyper-threaded CPUs, systems with multiple CPUs, and 
hibernating operating systems, the TSC cannot be relied on to provide accurate results 
— unless great care is taken to correct the possible flaws: rate of tick and whether 
all cores (processors) have identical values in their time-keeping registers. **There 
is no promise that the timestamp counters of multiple CPUs on a single motherboard will 
be synchronized**. In such cases, programmers can only get reliable results by locking 
their code to a single CPU. Even then, the CPU speed may change due to power-saving 
measures taken by the OS or BIOS, or the system may be hibernated and later resumed 
(resetting the time stamp counter). In those latter cases, to stay relevant, the 
counter must be recalibrated periodically (according to the time resolution your 
application requires).

这意味着现代 CPU 可以更改其 CPU 时钟频率以节省可能影响 TSC 值的功率。此外,TSC 永远不会在诸如内核可能执行 HALT 并停止处理器直到接收到外部中断的情况下增加。

the second question is that i have intel xeon i3 processor which has 4 processors & 
each having 2 cores then measuring the clock ticks will give the ticks of single 
processor or addition of all 4 processors..?

这可能会导致进程可以在一个处理器上读取时间,移动到第二个处理器并遇到比它在第一个处理器上读取的时间更早的时间,从而导致 TSC 成为不稳定的时间源。

于 2012-12-24T08:38:21.900 回答
2

所有内核都有自己的 TSC;它基本上计算周期 - 但要注意 - TSC 时钟可能不同步!如果您的代码开始在一个核心上运行并迁移到第二个核心,这在一般情况下当然是可能的,那么您的计数将是错误的!

于 2012-12-24T07:08:09.240 回答
2

这里提到的一些事情是准确的,例如由于 CPU 中的 S 状态,TSC 不是时间度量。但我认为即使在多核环境中,TSC 也可以用于相对排序。有一个名为 TSCInvariant 的标志在 Intel CPU >= nehalem arch 中设置为 true。在这些 CPU 中,TSC 在所有内核上以恒定速率变化。因此,如果您将上下文切换到不同的核心,您将永远不会返回 TSC 计数。

在 Ubuntu 中,您可以执行 sudo apt-get install cpuid

cpuid | grep TscInvariant 在您的桌面上验证它。

于 2015-10-28T22:53:41.863 回答