ein*_*ica 5 c++ linux multithreading scheduling thread-priority
我正在运行一个进程(在基于Linux 3.x的操作系统上),其中:
可能存在超额订购(即,使用HT的英特尔处理器上的工作线程数超过核心的两倍).现在,我看到的是'经理'线程没有足够频繁地获得处理器时间.他们并非完全'挨饿',我只是想给他们一个提升.所以,我自然而然地想到设置不同的线程优先级(我在Linux上) - 但后来我注意到线程调度程序的不同选择及其效果.此时我感到困惑,或者更确切地说 - 我不清楚:
笔记:
UPD 12.02.2015:我做了一些实验.
将"管理器"线程调度程序更改为RT(提供SCHED_DEADLINE/SCHED_FIFO策略的实时调度程序)有明显的解决方案.在这种情况下,"管理器"线程将始终具有比系统中大多数线程更大的优先级,因此它们几乎总是在需要时获得CPU.
但是,还有另一种解决方案可以让您继续使用CFS调度程序.您对"工人"线程的目的描述与批处理调度类似(在古代,当计算机很大时,用户必须将他的工作放到队列中并等待数小时才能完成).Linux CFS通过SCHED_BNCH策略和对话作业通过SCHED_NORMAL策略支持批处理作业.
内核代码中有一些有用的注释(kernel/sched/fair.c):
/*
* Batch and idle tasks do not preempt non-idle tasks (their preemption
* is driven by the tick):
*/
if (unlikely(p->policy != SCHED_NORMAL) || !sched_feat(WAKEUP_PREEMPTION))
return;
Run Code Online (Sandbox Code Playgroud)
因此,当"管理器"线程或其他事件唤醒"工作者"时,后者只有在系统中有空闲CPU或"管理器"耗尽其时间片(调整它改变任务的权重)时才会获得CPU.
如果不更改调度程序策略,似乎无法解决您的问题.如果"工人"线程很忙并且"经理"很少醒来,他们会获得相同的vruntime奖金,因此"工人"总是会抢占"经理"线程(但你可能会增加他们的体重,所以他们会更快地耗尽他们的奖金) .
我有一台带有2个Intel Xeon E5-2420 CPU的服务器,它为我们提供了24个硬件线程.为了模拟两个线程池,我使用了自己的TSLoad工作负载生成器(并在运行实验时修复了几个错误:)).
有两个tp_manager线程池:有4个线程和tp_worker30个线程,两个都运行busy_wait工作负载(只是for(i = 0; i < N; ++i);)但具有不同的循环周期数.tp_worker在benchmark模式下工作,因此它将尽可能多地运行请求并占用100%的CPU.
以下是示例配置:https://gist.github.com/myaut/ad946e89cb56b0d4acde
3.12(带调试配置的vanilla)
EXP | MANAGER | WORKER
| sched wait service | sched service
| policy time time | policy time
33 | NORMAL 0.045 2.620 | WAS NOT RUNNING
34 | NORMAL 0.131 4.007 | NORMAL 125.192
35 | NORMAL 0.123 4.007 | BATCH 125.143
36 | NORMAL 0.026 4.007 | BATCH (nice=10) 125.296
37 | NORMAL 0.025 3.978 | BATCH (nice=19) 125.223
38 | FIFO (prio=9) -0.022 3.991 | NORMAL 125.187
39 | core:0:0 0.037 2.929 | !core:0:0 136.719
Run Code Online (Sandbox Code Playgroud)
3.2(股票Debian)
EXP | MANAGER | WORKER
| sched wait service | sched service
| policy time time | policy time
46 | NORMAL 0.032 2.589 | WAS NOT RUNNING
45 | NORMAL 0.081 4.001 | NORMAL 125.140
47 | NORMAL 0.048 3.998 | BATCH 125.205
50 | NORMAL 0.023 3.994 | BATCH (nice=10) 125.202
48 | NORMAL 0.033 3.996 | BATCH (nice=19) 125.223
42 | FIFO (prio=9) -0.008 4.016 | NORMAL 125.110
39 | core:0:0 0.035 2.930 | !core:0:0 135.990
Run Code Online (Sandbox Code Playgroud)
一些说明:
nice可以间接设置)稍微减少等待时间.