gpt4 book ai didi

linux - 为什么使用 taskset 在一组孤立的内核上运行多线程 Linux 程序会导致所有线程都在一个内核上运行?

转载 作者:IT王子 更新时间:2023-10-29 00:14:39 25 4
gpt4 key购买 nike

期望的行为:在使用 isolcpus 隔离的一组内核上运行多线程 Linux 程序。

这是一个我们可以用作示例多线程程序的小程序:

#include <stdio.h>
#include <pthread.h>
#include <err.h>
#include <unistd.h>
#include <stdlib.h>

#define NTHR 16
#define TIME 60 * 5

void *
do_stuff(void *arg)
{
int i = 0;

(void) arg;
while (1) {
i += i;
usleep(10000); /* dont dominate CPU */
}
}

int
main(void)
{
pthread_t threads[NTHR];
int rv, i;

for (i = 0; i < NTHR; i++) {
rv = pthread_create(&threads[i], NULL, do_stuff, NULL);
if (rv) {
perror("pthread_create");
return (EXIT_FAILURE);
}
}
sleep(TIME);
exit(EXIT_SUCCESS);
}

如果我在没有独立 CPU 的内核上编译和运行它,那么线程将分布在我的 4 个 CPU 上。好!

现在,如果我将 isolcpus=2,3 添加到内核命令行并重新启动:

  • 在没有任务集的情况下运行程序会将线程分布在核心 0 和 1 上。这是预期的,因为默认的关联掩码现在不包括核心 2 和 3。
  • 使用taskset -c 0,1 运行具有相同的效果。好。
  • 使用 taskset -c 2,3 运行会导致所有线程进入同一核心(核心 2 或 3)。这是不希望的。线程应该分布在核心 2 和 3 上。对吗?

This post描述了一个类似的问题(尽管给出的示例离 pthreads API 更远)。 OP 很高兴通过使用不同的调度程序来解决这个问题。不过,我不确定这是否适合我的用例。

有没有办法使用默认调度程序将线程分布在独立的核心上?

这是我应该报告的内核错误吗?

编辑:

如果您使用像 fifo 调度程序这样的实时调度程序,那么正确的事情确实会发生。有关详细信息,请参见 man schedman chrt

最佳答案

来自 Linux 内核参数文档:

This option can be used to specify one or more CPUs to isolate from the general SMP balancing and scheduling algorithms.

因此,此选项将有效地阻止调度程序将线程从一个核心迁移到另一个竞争较少的核心(SMP 平衡)。由于典型的 isolcpus 与 pthread 亲和力控制一起使用,以固定具有 CPU 布局知识的线程,以获得可预测的性能。

https://www.kernel.org/doc/Documentation/kernel-parameters.txt

--编辑--

好的,我明白你为什么感到困惑了。是的,我个人会假设此选项的行为一致。问题出在两个函数上,select_task_rq_fair 和 select_task_rq_rt,它们负责选择新的 run_queue(本质上是选择在哪个 next_cpu 上运行)。我对这两个函数进行了快速跟踪(Systemtap),对于 CFS,它总是返回掩码中相同的第一个核心;对于 RT,它将返回其他核心。我没有机会研究每个选择算法中的逻辑,但您可以向 Linux 开发邮件列表中的维护者发送电子邮件以进行修复。

关于linux - 为什么使用 taskset 在一组孤立的内核上运行多线程 Linux 程序会导致所有线程都在一个内核上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36604360/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com