How is each process pinned to a specific core by scheduler (Linux)
我现在正在研究Linux的调度程序。关于CPU核心亲和力,我想知道以下内容:
1)每个进程(线程)如何固定到核心?
有一个系统调用
1 2 3 4 | printk(KERN_INFO"%d %d %ld %lu %s ", current->pid, current->tgid, current->state, current->cpus_allowed, current->comm); |
似乎在
2)是否可以通过PID或其他信息获取核心ID?
这是我想在Linux内核中实现的。在
谢谢,
每个CPU都有自己的runqueue,AFAIK我们可以通过查找它所属的runqueue找到进程的当前CPU。给定
我在实践中没有尝试过这个,只是在线阅读一些代码,并且我不太确定它是否可行。希望它可以帮到你。
您可以使用其task_struct确定运行线程的CPU ID:
1 2 3 4 | #include <linux/sched.h> task_struct *p; int cpu_id = task_cpu(p); |
例如。:
1 2 | #cat /proc/6128/stat 6128 (perl) S 3390 6128 3390 34821 6128 4202496 2317 268 0 0 1621 59 0 0 16 0 1 0 6860821 10387456 1946 18446744073709551615 1 1 0 0 0 0 0 128 0 18446744073709551615 0 0 17 8 0 0 0 |
过程6128在核心8上运行。
CPU核心关联性是特定于操作系统操作系统知道如何执行此操作,您不必这样做。如果您指定要运行哪个核心,可能会遇到各种问题,其中一些核心实际上可能会减慢进程。
在Linux内核中,与进程task_struct关联的数据结构包含cpu_allowed位掩码字段。对于机器中的每个n个处理器,这包含n位。具有四个物理核心的机器将具有四个位。如果这些CPU核心是超线程启用的,那么它们将具有8位位掩码。如果为给定进程设置了给定位,则该进程可以在关联的核上运行。因此,如果允许进程在任何核心上运行并允许根据需要跨处理器迁移,则位掩码将完全为1秒。实际上,这是Linux下进程的默认状态。例如,
1 | PID 2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3 |
进程2441具有0x3的CPU亲和性,这意味着它可以在Core0和Core1中使用。
应用程序还可以通过更改位掩码使用Kernel API sched_set_affinity()指定/设置关联。