用TSC(时间戳计数器)计算时间

我正在尝试用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位寄存器 。 所以,如果我有双核心处理器,这个计数器会出现在两个核心还是只有一个,因为它只有一个处理器,而双核心?

第二个问题是:我有带有4个处理器的Intel Xeon i3处理器,每个处理器有2个内核。 然后,测量时钟滴答,将给单处理器的滴答声或添加所有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 ); } 

alernatitvely,作为一个函数返回一个值:

 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的指针,这让我怀疑你实际上并没有把时间戳记计数器传递给调用者,而只是保持它发生的任何值 – 这可能是两个值相同。

同样的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值的电源。 当内核可以执行HALT并停止处理器直到接收到外部中断时,TSC也不会增加。

 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成为不稳定的时间源。

所有核心都有自己的TSC; 它基本上是计数周期 – 但要小心 – TSC时钟可能不同步! 如果你的代码开始在一个核心上运行,并迁移到第二个,这在一般情况下肯定是可能的,你的计数将是错误的!

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

在Ubuntu中,你可以做sudo apt-get install cpuid

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