大概有一个库或简单的 asm blob 可以让我知道我正在执行的当前 CPU 的数量。
4 回答
用于sched_getcpu
确定正在运行调用线程的 CPU。请参阅man getcpu
(系统调用)和man sched_getcpu
(库包装器)。但是,请注意它所说的:
放置在 cpu 中的信息仅保证在调用时是最新的:除非使用 sched_setaffinity(2) 修复了 CPU 亲和性,否则内核可能随时更改 CPU。(通常这不会发生,因为调度程序会尽量减少 CPU 之间的移动以保持高速缓存热,但这是可能的。)调用者必须准备好处理当 cpu 和节点不再是当前 CPU 和节点的情况。
您需要执行以下操作:
- 调用 sched_getaffinity 并识别 CPU 位
- 迭代 CPU,对每个 CPU 执行 sched_setaffinity (我不确定在 sched_setaffinity 之后你是否保证在 CPU 上,或者需要显式让步?)
- 执行 CPUID(asm 指令)...有一种方法可以从其中一个输出中获取唯一的每核 ID(请参阅Intel 文档)。我隐约记得它是“APIC ID”。
- 从 APIC ID 到 CPU 编号或关联掩码或其他东西构建一个表(一个 std::map ?)。
- 如果您在主线程上执行此操作,请不要忘记将 sched_setaffinity 设置回所有 CPU!
现在,您可以在需要时再次使用 CPUID 并查找您所在的内核。
但我想问你为什么需要这样做;通常你想通过 sched_setaffinity 来控制而不是找出你在哪个核心上(即使这是一个非常罕见的东西想要/需要)。(这就是为什么我不知道从 CPUID 中准确提取什么的关键细节,抱歉!)
更新:刚刚从 litb 的回复中了解了 sched_getcpu。好多了!(不过我的 Debian/etch libc 太旧了,无法使用)。
我不知道有什么可以获取您当前的核心 ID。使用内核级任务/进程迁移,除非您以某种形式的实时模式运行,否则无法保证它会在任何时间长度内保持不变。
如果你想在一个特定的核心上,你可以使用那个sched_setaffinity()
函数或taskset
命令来启动你的程序。不过,我相信这些需要提升的权限才能工作。然后,在您的程序中,您可以运行sched_getaffinity()
以查看之前设置的掩码,并将其用作您正在执行的核心的最佳猜测。
sysconf(_SC_NPROCESSORS_ONLN);