每个进程如何通过调度程序固定到特定的核心(Linux)

发布于 2025-01-03 16:42:39 字数 729 浏览 4 评论 0 原文

我现在正在研究Linux的调度器。关于CPU核心亲和力,我想知道以下内容:

1)每个进程(线程)如何固定到核心?

有一个系统调用 sched_setaffinity 来更改执行进程的核心关联性。但在内部,当生成一个进程(或线程)时,默认的Linux调度程序如何将进程(线程)分配给特定的核心?我修改了 sched_setaffinity 系统调用来转储有关任务从一个核心移动到另一个核心的信息。

printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid,
                                       current->state, current->cpus_allowed,
                                       current->comm);

/var/log/messages 中似乎没有上述信息的转储。因此,默认调度程序以不同的方式固定每个进程,但我不知道如何进行。

2)是否可以通过PID或其他信息获取核心ID?

这就是我想在 Linux 内核内部实现的内容。在task_struct中,有一个名为cpus_allowed的成员。但这是设置亲和力的掩码,而不是核心 ID。我想检索标识正在运行指定进程的核心的数据。

谢谢,

I am now studying about the scheduler of Linux. Regarding CPU core affinity, I would like to know the following:

1) How is each process(thread) pinned to a core?

there is a system call sched_setaffinity to change the core affinity on which a process is executed. But internally, when a process(or a thread) is generated, how does the default Linux scheduler assign the process(thread) to a specific core? I modified sched_setaffinity system call to dump information about the task being moved from one core to another.

printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid,
                                       current->state, current->cpus_allowed,
                                       current->comm);

It seems that there is no dump of the above information in /var/log/messages. So the default scheduler pins each process in a different way, but I cannot figure out how.

2) Is it possible to get core ID by PID or other information?

This is what I want to implement inside of Linux kernel. In task_struct, there is a member called cpus_allowed. But this is a mask for setting affinity, not core ID. I want to retrieve a data identifying the core on which specified process is running.

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沫尐诺 2025-01-10 16:42:39

每个CPU都有自己的运行队列,AFAIK我们可以通过查找进程所属的运行队列来找出进程当前的CPU。给定task_struct *p,我们可以通过struct rq = task_rq(p)得到它的运行队列,struct rq有一个名为cpu,我想这应该是答案。

我没有在实践中尝试过这个,只是在线阅读了一些代码,并且不太确定它是否有效。希望它可以帮助你。

Each CPU has its own runqueue, AFAIK we can find out current CPU of a process by looking for which runqueue it belongs to. Given task_struct *p, we can get its runqueue by struct rq = task_rq(p), and struct rq has a field named cpu, I guess this should be the answer.

I have not tried this in practice, just read some code online, and am not quite sure it it will work or not. Wish it could help you.

短叹 2025-01-10 16:42:39

您可以使用线程的task_struct 来确定正在运行的线程的CPU ID:

#include <linux/sched.h>

task_struct *p;
int cpu_id = task_cpu(p);

You can determine the CPU ID on which a thread is running by using its task_struct:

#include <linux/sched.h>

task_struct *p;
int cpu_id = task_cpu(p);
樱&纷飞 2025-01-10 16:42:39

/proc/pid/stat 中的字段 39 告诉进程当前的 core/cpu。

例如:

#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 上运行。

Field 39 in /proc/pid/stat tells the current core/cpu of the process.

e.g.:

#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

Process 6128 is running on core 8.

驱逐舰岛风号 2025-01-10 16:42:39

CPU 核心关联性是特定于操作系统的。操作系统知道如何执行此操作,您不必这样做。如果指定在哪个核心上运行,您可能会遇到各种问题,其中一些问题实际上可能会减慢进程速度。

在Linux内核中,与进程相关的数据结构task_struct包含cpu_allowed位掩码字段。它包含 n 个位,每个位对应机器中的 n 个处理器。具有四个物理核心的机器将有四个位。如果这些 CPU 核心支持超线程,它们将具有八位位掩码。如果为给定进程设置了给定位,则该进程可以在关联的核心上运行。因此,如果允许进程在任何内核上运行并允许根据需要跨处理器迁移,则位掩码将完全为 1。事实上,这是 Linux 下进程的默认状态。例如,

PID  2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3

进程2441的CPU亲和性为0x3,这意味着它可以在Core0和Core1中使用。

应用程序还可以使用内核 API sched_set_affinity() 通过更改位掩码来指定/设置关联性。

CPU core affinity is OS specific. The OS knows how to do this, you do not have to. You could run into all sorts of issues if you specified which core to run on, some of which could actually slow the process down.

In Linux Kernel, the data structure associated with processes task_struct contains cpu_allowed bitmask field. This contains n bits one for each of n processors in the machine. A machine with four physical core's would have four bits. If those CPU core's were hyperthread-enabled they would have an eight-bit bitmask. If a given bit is set for a given process, that process may run on the associated core. Therefore, if a process is allowed to run on any core and allowed to migrate across processors as needed, the bitmask would be entirely 1s. This is in fact, the default state for processes under Linux. For example,

PID  2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3

the process 2441 has a CPU affinity of 0x3, which means it can used in Core0 and Core1.

The applications can also specify/set the affinity using Kernel API sched_set_affinity() by altering the bitmask.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文