当你想限制每个进程的 CPU 时间时,你可以通过cgroups
. 有两个参数可以完成这项工作:cpu.cfs_period_us
和cpu.cfs_quota_us
.
- cpu.cfs_period_us:每个调度程序周期的持续时间(以微秒为单位),用于带宽决策。这默认为 100000us 或 100ms。更长的周期会以延迟为代价来提高吞吐量,因为调度程序将能够更长时间地维持 CPU 绑定的工作负载。较小时期的情况正好相反。请注意,这只影响由 CFS 调度程序调度的非 RT 任务。
- cpu.cfs_quota_us:允许当前组在每个 cfs_period_us 中运行的最长时间(以微秒为单位)。例如,如果它设置为 cpu_period_us 的一半,cgroup 将只能在 50% 的时间内达到峰值运行。应该注意的是,这表示系统中所有 CPU 的总时间。因此,例如,为了允许两个 CPU 的充分使用,应该将此值设置为 cfs_period_us 值的两倍。
假设我想将一个进程限制为 1 个 CPU 核心。这可以通过以下方式完成:
cpu.cfs_quota_us 1.000.000
cpu.cfs_period_us 1.000.000
对比
cpu.cfs_quota_us 100.000
cpu.cfs_period_us 100.000
对比
cpu.cfs_quota_us 10.000
cpu.cfs_period_us 10.000
这三个选项有什么区别?假设我有一个 Firefox 进程,什么cpu.cfs_period_us
对它更好——更长或更短,为什么?
正如报价所说,较低的数字会降低延迟。一个进程在被调度之前不必等待很长时间:每个进程很快就会轮到它。但是有更多的重新调度开销:每次时间用完,并且有其他进程准备运行时,都会重新调度。
重新调度包括将所有寄存器保存在堆栈上,将堆栈指针保存到任务控制块中,切换任务控制块,禁用/启用部分虚拟页表,重新加载堆栈指针,以及恢复寄存器。它还可能导致更多的缓存未命中。所以简而言之,事情运行得更慢。
对于长时间运行的非交互式任务,较长的调度程序周期更好。批处理调度程序具有更长的调度程序周期,并且以低于标准交互式调度程序的优先级运行。