我该如何查找我正在运行的CPU/核心?

3
为了进行基准测试,我使用 rdtsc 来确定在关键循环内执行某些代码块所花费的伪时间。由于我的代码可以在任何时候在进程之间重新调度,因此我希望通过仅在发现在微观测量的开始和停止之间更改了 CPU 时转储数据来最小化噪音。

有没有 x86 指令可以用来识别我正在运行的 CPU/核心?是否有一些可以给我一个唯一标识符或 CPU#和 core#等信息的东西。

显然,cpuid 不再提供该信息,因此我正在寻找替代方案。


2
你使用自己的操作系统吗?因为Windows和Linux都有API可以完成你所需的功能:分别是GetCurrentProcessorNumbersched_getcpu - user781847
1
你应该将线程固定到单个核心。另请参阅此问题 - Jester
1
该程序采用英特尔的MP初始化协议来唤醒可能存在的任何辅助处理器,并允许每个处理器显示其APIC本地ID。[链接]http://www.cs.usfca.edu/~cruse/cs630/mphello.s - Dirk Wolfgang Glomp
@Jester 我在实践中做不到这一点,否则我的用户会讨厌我 :) - Yoric
@knm241Ah,我之前不知道这些,谢谢。你有没有想法它们的速度有多快?如果活动量很大,我的循环每帧执行约10k次迭代,所以我不想因为检查基准数是否正确而减慢速度。 - Yoric
显示剩余2条评论
1个回答

1
不完全正确。你并不需要一个单独的指令,因为在执行指令后,你的线程可能会立即迁移到另一个核心,并且在你能够对其结果做出有用操作之前(或在RDTSC和“我在哪个核心上?”检查之间),你就无法进行任何有用操作。 RDTSCP很方便地避免了这种情况,因为它既提供了TSC,又以单个指令返回了操作系统告诉它的任何内容,但它需要操作系统支持并且是序列化指令(比RDTSC更重量级,可能会影响细粒度计时测量)。
正如评论中有人指出的那样,如果每个测量的精度对您很重要,您可能需要使用操作系统API来固定线程以确保它不会迁移。 或者,迁移相对较少,因此如果您可以进行足够的测量,则由其引起的偶发异常值将明显且易于排除。

我非常清楚从RDTSC调用迁移到假设的RDWHEREAMI之间的可能性。 我不需要强有力的保证,即我的最后一次对RDTSC的调用在与第一次调用相同的CPU上,但是我希望能够测量这种情况发生的频率(大致由RDWHEREAMI覆盖),以便我可以调整我的统计数据(或者至少得到保证)。 - Yoric
@Yoric,我坚信如果你只关心性能统计数据,并且你正在测量足够小的代码块以使RDTSC重要,则迁移应该很少并且明显是异常值,就像上下文切换一样。无论如何,识别处理器ID是特定于操作系统的。如果您的操作系统适当地设置了TSC_AUX MSR,则RDTSCP可以帮助。否则,我知道在Windows上GetCurrentProcessorNumber()很便宜(它避免了系统调用)。我不确定Linux的等效物。 - ab.
实际上,我正在测量一块相当大的代码,它每秒运行几千到几百万次,并且我开始使用“RDTSC”,仅因为我的先前尝试显然减慢了这个关键循环。 我认为该代码不经常迁移,但是具有在跨平台,无系统调用方式中进行测量的方法将很好地得到现实世界的确认。 同时,我使用'GetCurrentProcessorNumber()'和'sched_getcpu'(对于mach/MacOS X我没有发现任何等效物)。 - Yoric

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