【问题标题】:How do I find on which CPU/core I'm running?如何找到我正在运行的 CPU/内核?
【发布时间】:2015-07-20 13:59:42
【问题描述】:

出于基准测试的目的,我使用rdtsc 来确定我在关键循环中执行某些代码块所花费的伪时间。由于我的代码可以随时在进程之间重新调度,如果我发现我在微措施的开始和停止之间更改了 CPU,我想通过转储数据来最小化噪音。

是否有 x86 指令可以用来识别我在哪个 CPU/内核上运行?可以给我一个唯一标识符或 CPU# 和 core# 等的东西。

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

【问题讨论】:

  • 您使用自己的操作系统吗?因为 Windows 和 Linux 都有 API 来满足您的需求:分别为 GetCurrentProcessorNumbersched_getcpu
  • 你应该把你的线程固定到一个核心上。另请参阅this question
  • 如果您的 CPU 将提供该信息,它将通过 cpuid 提供。但这不是出于安全原因。
  • 该程序使用 Intel 的 MP 初始化协议来唤醒任何可能存在的辅助处理器,并允许每个处理器显示其 APIC 本地 ID。 [链接]cs.usfca.edu/~cruse/cs630/mphello.s
  • @Jester 在实践中我不能这样做,否则我的用户会恨我:)

标签: c assembly x86


【解决方案1】:

不是真的。您真的不想要单独的指令,因为您的线程可能在执行指令后立即迁移到另一个内核,并且在您对其结果做任何有用的事情之前(或在 RDTSC 和“我在哪个内核上?”查看)。 RDTSCP 方便地避免了这种情况,因为它既提供 TSC 又返回操作系统在单个指令中告诉它的任何内容,但它需要操作系统支持并且是一个序列化指令(比 RDTSC 更重量级,这可能会影响细粒度的时序测量) .

正如 cmets 中有人指出的那样,如果每次测量的精度对您来说都很重要,您可能需要使用操作系统 API 来固定线程以确保它不会迁移。或者,迁移相对较少,因此如果您可以进行足够的测量,那么它导致的偶尔异常值将很明显并且很容易排除。

【讨论】:

  • 我很清楚在调用RDTSC 和假设的RDWHEREAMI 之间迁移的可能性。我不想强烈保证我对RDTSC 的最后一次调用与我的第一次调用在同一个 CPU 上,但我希望能够测量有多少次不是这种情况(应该大致涵盖RDWHEREAMI),这样我就可以调整我的统计数据(或者至少可以放心)。
  • @Yoric,我坚持我的断言,如果您只关心性能统计数据,并且您正在测量足够小的代码块以使 RDTSC 变得重要,那么迁移应该是罕见且明显的异常值,很像上下文切换。在任何情况下,识别处理器 ID 都是特定于操作系统的。如果您的操作系统正确设置了 TSC_AUX MSR,那么 RDTSCP 可以提供帮助。否则,我知道GetCurrentProcessorNumber() 在 Windows 上很便宜(它避免了系统调用)。我不确定 Linux 的等价物。
  • 实际上,我正在测量一个相当大的代码块,它恰好每秒运行几千到几百万次,我开始使用 RDTSC 只是因为我以前的尝试显然减慢了这个关键循环。我认为代码不会经常迁移,但是如果能够以跨平台、无系统调用的方式对其进行测量,那么得到现实世界的确认会很好。与此同时,我使用GetCurrentProcessorNumber()sched_getcpu(我还没有找到任何与 mach/MacOS X 等效的东西)。
猜你喜欢
  • 1970-01-01
  • 2014-03-12
  • 2017-08-22
  • 1970-01-01
  • 2016-08-28
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多