如何在用户空间应用程序中获取CPU核心数量(Linux,C)?

18

可能有一个库或简单的汇编代码块可以获取我正在执行的当前CPU的编号。


我非常确定之前有过这样的问题,但我找不到它。 - Tamas Czinege
在内核中确定这一点并不太困难,但我(非常)确定没有用户空间的方法可以找到这个问题的答案。投票支持,希望我是错误的,好问题 :) - Tim Post
4个回答

22
使用sched_getcpu函数可确定调用线程所在的CPU。请参阅man getcpu(系统调用)和man sched_getcpu(库包装器)。但请注意以下内容:
引用如下:

放置在cpu中的信息只在调用时保证是当前的:除非使用sched_setaffinity(2)固定了CPU亲和力,否则内核可能随时更改CPU。(通常不会发生,因为调度程序试图最小化在CPU之间的移动以保持缓存热,但是有可能发生。) 调用者必须准备好处理当cpu和node不再是当前CPU和节点时的情况。


你也可以看一下hwloc(http://www.open-mpi.org/projects/hwloc/)。使用它,你可以访问完整的拓扑结构(缓存/核心等),而且它应该是可移植的。 - Ben
在这里,我提供了一个具体的 sched_setaffinity + sched_getcpu C 示例:https://dev59.com/DGkv5IYBdhLWcg3wlR31#50117787 - Ciro Santilli OurBigBook.com

5
您需要做以下操作:
  • 调用sched_getaffinity并识别CPU位
  • 迭代CPU,对每个CPU执行sched_setaffinity (我不确定在sched_setaffinity之后是否保证在CPU上,或者需要显式地yield?)
  • 执行CPUID(asm指令)...有一种方法可以从其中一个输出中获取唯一的每个核心ID(请参见Intel文档)。 我模糊地记得它是“APIC ID”。
  • 从APIC ID构建表格(std :: map?)到CPU编号或亲和力掩码等。
  • 如果您在主线程上执行此操作,请不要忘记将sched_setaffinity设置回所有CPUS!

现在,每当需要时,您都可以再次使用CPUID并查找所在的核心。

但我想询问为什么您需要这样做;通常情况下,您希望通过sched_setaffinity来控制,而不是找出您在哪个核心上(即使这也是一个相当罕见的需求/需要)。 (这就是为什么我不知道从CPUID中提取什么关键细节,抱歉!)
更新:刚刚从litb的回复中了解到sched_getcpu。更好了!(我的Debian / etch libc太旧了,没有它)。

2

我不知道有什么方法可以获取当前的核心id。若使用内核级别的任务/进程迁移,不能保证它会在任何时间段内保持不变,除非你正在运行某种实时模式。

如果你想要运行在特定的核心上,你可以使用 sched_setaffinity() 函数或 taskset 命令来启动你的程序。我相信这些需要提升的权限才能工作。在你的程序中,你可以运行 sched_getaffinity() 来查看之前设置的掩码,并将其用作你正在执行的核心的最佳猜测。


-1
sysconf(_SC_NPROCESSORS_ONLN);

那对我有用。为什么你的答案被踩了?sched_*依赖于glibc,而sched_getcpu在我的电脑上返回了一个无效的核心数(Ubuntu 13.10 64位,Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz)。 - Jean
2
这个被踩的原因是因为这个调用会给你核心(处理器)的数量,而不是当前核心的ID(问题所要求的)。 - Torandi

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