Nice 级别在 Linux 上无法使用

Nice 级别在 Linux 上无法使用

我有一些高度浮点密集型的进程,但 I/O 操作很少。其中一个进程称为“xspec”,它每秒计算一个数值模型并向主进程返回一个浮点结果(通过 stdout)。它的优化级别为 19。我还有另一个简单的进程“cpufloattest”,它只是在紧密循环中进行数值计算。它没有优化。

我有一个 4 核 i7 系统,并且禁用了超线程。我已启动了每种类型的 4 个进程。为什么 Linux 调度程序 (Linux 3.4.2) 没有正确限制经过优化的进程所占用的 CPU 时间?

CPU:56.2%us,1.0%sy,41.8%ni,0.0%id,0.0%wa,0.9%hi,0.1%si,0.0%st
内存:总计 12297620k,已用 12147472k,可用 150148k,缓冲区 831564k
交换:总计 2104508k,已使用 71172k,可用 2033336k,缓存 4753956k

  PID 用户 PR NI VIRT RES SHR S %CPU %MEM TIME+ 命令                                         
32399 jss 20 0 44728 32m 772 R 62.7 0.3 4:17.93 cpufloattest                                    
32400 jss 20 0 44728 32m 744 R 53.1 0.3 4:14.17 cpufloat测试                                    
32402 jss 20 0 44728 32m 744 R 51.1 0.3 4:14.09 cpufloat测试                                    
32398 jss 20 0 44728 32m 744 R 48.8 0.3 4:15.44 cpufloattest                                    
 3989 jss 39 19 1725米 690米 7744 R 44.1 5.8 1459:59 xspec                                           
 3981 jss 39 19 1725米 689米 7744 R 42.1 5.7 1459:34 xspec                                           
 3985 jss 39 19 1725米 689米 7744 R 42.1 5.7 1460:51 xspec                                           
 3993 jss 39 19 1725米 691米 7744 R 38.8 5.8 1458:24 xspec                                           

如果我启动 8 个 cpufloattest 进程,其中 4 个是经过优化的(即 4 个占用大部分 CPU,4 个占用很少的 CPU),调度程序就会按我的预期运行。

答案1

我发现了导致此问题的原因。这是由于 CFS 调度程序的“自动分组”功能造成的。如果我

echo 0 > /proc/sys/kernel/sched_autogroup_enabled 

然后一切都会按照您预期的方式运行。当 nice 0 进程运行时,nice 19 进程的 CPU 使用率会降至接近零。

我将尝试准确找出自动分组如何破坏我的使用情况并更新此答案。

编辑...我在 IRC 上和一些内核人员聊天,他们说如果它不适合我的工作量,我应该禁用它,而且它只是 Linus 喜欢的一个疯狂补丁。我不确定为什么自动分组不适合我的工作量,但这个答案是为遇到类似问题的人提供的。

答案2

为已接受的答案添加更多细节...您看到的行为是由于 Linux 2.6.38(2010 年)中添加的自动分组功能。假设在描述的场景中,这两个命令是在不同的终端窗口。如果它们在相同的终端窗口,那么你应该已经看到 nice 值产生了效果。本答案的其余部分详细说明了这个故事。

内核提供了一个称为自动分组的功能,用于在面对多进程、CPU 密集型工作负载(例如使用大量并行构建进程构建 Linux 内核)时提高交互式桌面的性能(即标志make(1) -j)。

当通过 创建新会话时,将创建一个新的自动组setsid(2);例如,当启动新的终端窗口时,就会发生这种情况。通过 创建的新进程fork(2)将继承其父进程的自动组成员身份。因此,会话中的所有进程都是同一自动组的成员。

当启用自动分组时(这是许多发行版的默认设置),自动组的所有成员都会被放置在同一个内核调度程序“任务组中”。Linux 内核调度程序采用一种算法来均衡任务组之间的 CPU 周期分配。以下示例可以描述此算法对交互式桌面性能的好处。

假设有两个自动组竞争同一个 CPU(即,假设使用单 CPU 系统或使用 将taskset(1) 所有进程限制在 SMP 系统上的同一个 CPU 上)。第一个组包含十个 CPU 绑定进程,它们来自以 开始的内核构建make -j10。另一个组包含一个 CPU 绑定进程:视频播放器。自动分组的效果是两个组将各自获得一半的 CPU 周期。也就是说,视频播放器将获得 50% 的 CPU 周期,而不是仅仅 9% 的周期,这可能会导致视频播放质量下降。SMP 系统上的情况更为复杂,但总体效果是一样的:调度程序在任务组之间分配 CPU 周期,以便包含大量 CPU 绑定进程的自动组不会以牺牲系统上其他作业为代价而占用 CPU 周期。

超值优惠和团体安排

在调度非实时进程(例如,在默认SCHED_OTHER策略下调度的进程)时,调度程序采用一种称为“组调度”的技术,在该技术下,线程被调度到“任务组中”。任务组在各种情况下形成,这里相关的情况是自动分组。

如果启用了自动分组,则所有(隐式)放置在自动组中的线程(即由 创建的同一会话setsid(2))将形成一个任务组。因此,每个新的自动组都是一个单独的任务组。

在组调度下,线程的 nice 值会影响调度决策仅相对于同一任务组中的其他线程。这在 UNIX 系统上 nice 值的传统语义方面产生了一些令人惊讶的后果。特别是,如果启用了自动分组,则nice(1)对进程的采用仅对相对于在同一会话中执行的其他进程(通常是:同一个终端窗口)的调度有影响。

相反,对于两个进程,如果它们是不同会话中唯一的 CPU 密集型进程(例如,不同的终端窗口,每个窗口的作业都绑定到不同的自动组),则修改其中一个会话中进程的 nice 值不会影响调度程序相对于另一个会话中进程的决策。这大概就是您看到的场景,尽管您没有明确提到使用两个终端窗口。

如果您想防止自动分组干扰nice此处描述的传统行为,那么,如接受的答案中所述,您可以禁用该功能

echo 0 > /proc/sys/kernel/sched_autogroup_enabled

但请注意,这也会禁用自动分组功能旨在提供的桌面交互优势(参见上文)。

自动分组 nice 值

可以通过该文件查看进程的自动组成员身份/proc/[pid]/autogroup

$ cat /proc/1/autogroup
/autogroup-1 nice 0

此文件还可用于修改分配给自动组的 CPU 带宽。这是通过将“nice”范围内的数字写入文件来设置自动组的 nice 值来实现的。允许的范围是从 +19(低优先级)到 -20(高优先级)。

自动组 nice 设置与进程 nice 值含义相同,但适用于根据其他自动组的相对 nice 值将 CPU 周期分配给整个自动组。对于自动组内的进程,它收到的 CPU 周期将是自动组的 nice 值(与其他自动组相比)和进程的 nice 值(与同一自动组中的其他进程相比)的乘积。

答案3

也许不是确切地您正在寻找什么,但是您尝试过命令吗cpulimit?它在 Debian/Ubuntu 存储库中可用。

使用 ,cpulimit您可以调整允许任何进程占用的总体 CPU 时间百分比。另一种可能性是使用cgroups,但cpulimit更直接、更易于使用。

答案4

我想你的意思是将优先级提高?在这种情况下,你会想要使用负值..

在您的输出中,cpufloattest 的优先级高于 xspec。

编辑:您可以使用 taskset 来设置一个进程以使用特定的处理器,但在这种情况下这不是必需的。

相关内容