为什么每秒非自愿上下文切换?

时间:2012-12-26 06:58:34

标签: linux-kernel operating-system scheduling kernel

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

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

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

编辑:一些回复提出了其他方法。在走这条路之前,我首先想要理解为什么即使经过几个小时的运行,我每秒也会获得一次非自愿的上下文切换。例如,这是由CFS引起的吗?如果是这样,哪些参数又如何?

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

3 个答案:

答案 0 :(得分:12)

这是一个猜测,但是一个受过教育的人 - 因为你使用一个独立的CPU,调度程序不会安排任何除你自己之外的任务,只有一个例外 - 内核中的vmstat代码有一个计划器,用于调度单个工作队列每秒CPU上的项目每秒一次,以计算内存使用情况统计信息,这是您所看到的每秒计划的内容。

工作队列代码非常智能,如果核心是100%空闲,则不会调度工作队列内核线程,但如果它正在运行单个任务则不会。

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

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

我维护一个wiki,其中包含隔离CPU工作负载here的所有中断源。如果一个vmstat工作队列运行到下一个vmstat工作队列之间没有变化,我还有一个补丁,用于让vmstat不调度工作队列项 - 例如,如果CPU上的单个任务不使用任何动态内存,就会发生这种情况分配。但不确定它会对您有益 - 这取决于您的工作量。

答案 1 :(得分: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中获取它。

Source
Man page
修改
抱歉,您注意到了pthread标记;这个概念仍然存在,请查看此手册页: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_setschedparam.3.html

答案 2 :(得分:0)

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