6

操作系统是 RHEL 6 (2.6.32)。我已经隔离了一个核心,并在其上运行了一个计算密集型线程。/proc/{thread-id}/status 每秒显示一次非自愿上下文切换。

有问题的线程是 SCHED_NORMAL 线程,我不想更改它。

如何减少非自愿上下文切换的数量?这是否取决于 /proc/sys/kernel 中的任何调度参数?

编辑:一些回应提出了替代方法。在走这条路之前,我首先想了解为什么即使在运行数小时后,我每秒也只能获得一次非自愿的上下文切换。例如,这是由 CFS 引起的吗?如果是这样,哪些参数以及如何?

EDIT2:进一步澄清-我想回答的第一个问题如下:为什么我每秒进行一次非自愿上下文切换,而不是说每半秒或两秒切换一次?

4

3 回答 3

12

这是一个猜测,但有根据 - 因为您使用一个独立的 CPU,所以调度程序不会在其上调度除您自己的任务之外的任何任务,但有一个例外 - 内核中的 vmstat 代码有一个计时器,该计时器在每个任务上调度一个工作队列项CPU 每秒一次来计算内存使用统计信息,这就是您所看到的每秒调度的内容。

工作队列代码足够聪明,如果内核 100% 空闲,则不会调度工作队列内核线程,但如果它正在运行单个任务,则不会。

您可以使用ftrace验证这一点。如果 sched_switch 跟踪器显示您每隔一秒左右切换一次的实体(该值四舍五入到最接近的 jiffie 事件,并且当 cpu 空闲时计时器不计数,因此这可能会扭曲计时)是 events/CPU_NUMBER 任务(或旧内核的 keventd ),那么几乎 100% 的原因确实是vmstat_update函数将其计时器设置为在事件内核线程运行时每秒排队一个工作队列项。

请注意,vmstat 设置其计时器的周期是可配置的 - 您可以通过 vm.stat_interval sysctl旋钮将其设置为其他值。增加此值会降低此类中断的发生率,但会降低内存使用统计的准确性。

我在此处维护一个 wiki,其中包含对隔离 CPU 工作负载的所有中断源。如果在一个 vmstat 工作队列运行到下一个运行之间没有变化,我也有一个补丁可以让 vmstat 不安排工作队列项目 - 例如,如果你在 CPU 上的单个任务不使用任何动态内存,就会发生这种情况分配。不过,不确定它是否会让您受益——这取决于您的工作量。

于 2013-01-02T19:27:03.607 回答
0

我强烈建议您尝试优化代码本身,以便当它在 CPU 上运行时,您可以充分利用它。
无论如何,我不确定这是否可行,但无论如何都要尝试一下,让我们知道:

我基本上要做的只是将调度策略设置为 FIFO,然后为进程提供可能的最大优先级。

#include<sched.h>
struct sched_param sp = sched_get_priority_max(SCHED_FIFO);
int ret;

ret = sched_setscheduler(0, SCHED_FIFO, &sp);
if (ret == -1) {
  perror("sched_setscheduler");
  return 1;
}

请记住,您的进程所做的任何阻塞语句很可能会导致调度程序将其从 CPU 中取出。


手册页
编辑:
抱歉,刚刚注意到pthread标签;这个概念仍然成立,所以请查看此手册页: http ://www.kernel.org/doc/man-pages/online/pages/man3/pthread_setschedparam.3.html

于 2012-12-26T08:13:44.030 回答
0

如果你的专用 CPU 上每秒一个中断仍然太多,那么你真的不需要通过正常的调度程序。我是否可以建议实时和等时优先级,这可以让您的进程比通常的抢先机制更可靠地安排?

于 2012-12-26T09:39:55.790 回答