Edd*_*ett 10 linux multithreading scheduler affinity
期望的行为:在已经隔离的一组核上运行多线程Linux程序isolcpus
.
这是一个我们可以用作多线程程序示例的小程序:
#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);
}
Run Code Online (Sandbox Code Playgroud)
如果我在没有隔离CPU的内核上编译并运行它,那么线程将分布在我的4个CPU上.好!
现在,如果我添加isolcpus=2,3
到内核命令行并重新启动:
taskset -c 0,1
具有相同的效果.好.taskset -c 2,3
会导致所有线程进入同一个核心(核心2或3).这是不希望的.线程应该分布在核心2和3上.对吗?这篇文章描述了一个类似的问题(虽然给出的例子离pthreads API更远).OP很乐意通过使用不同的调度程序来解决这个问题.我不确定这对我的用例来说是理想的.
有没有办法使用默认调度程序将线程分布在隔离的核心上?
这是我应该报告的内核错误吗?
编辑:
如果您使用像fifo调度程序这样的实时调度程序,那么确实会发生正确的事情.查看man sched
并man chrt
了解详情.
来自 Linux 内核参数文档:
该选项可用于指定一个或多个 CPU 以与通用 SMP 平衡和调度算法隔离。
因此,此选项将有效防止调度程序将线程从一个核心迁移到另一个竞争较少的核心(SMP 平衡)。由于典型的 isolcpu 与 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 devel 邮件列表中的维护者发送电子邮件进行修复。
归档时间: |
|
查看次数: |
2748 次 |
最近记录: |