多核时钟计数器一致性

6

我正在尝试在内核模块中测量两个时间点之间的时钟计数器差异。 我使用名为get_ccnt()的以下函数,在特定时间获取时钟计数器值:

static __inline__ long long int get_ccnt(void)
{
    #if defined(__i386__)
        long long int x;
        __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
        return x;

    #elif defined(__x86_64__)
        unsigned int hi, lo;
        __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
        return ( (long long int)lo)|( ((long long int)hi)<<32 );

    #endif
}

我关注的是,我正在使用HP EliteBook 2530p,其中搭载了Intel Core 2 Duo SL9400 (规格参考)。
据我听说,在Nehalem之后的CPU上,所有核心具有一致的时钟计数器(如果我错了,请指出)。但是,Intel Core 2 Duo SL 9400的代号是Penryn。
因此,我认为如果一个内核模块在两个时间点之间从一个核心移动到另一个核心,则两个核心之间的一致性会受到影响,并且无法获得正确的时钟差异。
我的想法正确吗?如果是这样,是否有解决方法(例如,修复一个内核模块,不将其移动到另一个核心?)

我找到了这篇文章。 - LPs
非常感谢。看起来他/她正在尝试通过将处理器绑定到特定的CPU亲和力来解决问题。我会尝试并稍后检查它。 - Jeon
即使是多线程的应用程序,也不应该“在核心之间切换”。(每个线程都独立运行。)如果尝试在不同核心上分析两个线程,则可以独立计时每个核心的使用情况,并将两个结果相加以获得总时间。(假设您想坚持使用RDTSC。)或者强制所有线程都在同一个核心上运行。否则,在主线程上执行RDTSC应该返回正确的经过时间,以返回到该线程,而不管其他线程如何。但是,在几乎所有情况下,它都会产生抖动,因为内核/操作系统会根据其自己的方式分配和运行它们。 - rdtsc
@rdtsc,你的名字让你的回答更加可信。非常感谢。我有时间会去检查一下。 - Jeon
请适当标记您的问题。这与C语言几乎没有任何关系(而且这甚至不是C语言),但与您的操作系统有很大关系。对于您来说,“内核”是指Linux内核吗? - Jens Gustedt
只有在您拥有多个处理器、主板上的物理芯片时才会出现这个问题。像您的笔记本电脑一样,拥有多个内核的处理器不会出现这个问题。 - Hans Passant
1个回答

1

其中一条评论提到设置进程亲和度可以实现你想要的目标。我还建议制作一个自定义版本的get_ccnt(),将RDTSC替换为RDTSCP。后者是前者的变体,还返回cpuid与循环计数器。您可以检查初始测量的cpuid是否等于最终测量的cpuid。

请查看这个英特尔手册的第3.2节。确保先进行测试以验证您的处理器是否支持此指令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接