我正在对一些长时间运行的作业进行一些性能故障排除,这些作业启动消耗整个 CPU 核心的进程,但是是单线程的。我观察到这些进程不断地跳到不同的 CPU。为什么相同的进程会移动到不同的CPU上?内核调度程序如此频繁地移动正在运行的进程,或者根本不移动,这似乎并不正常。然而,我在许多不同的进程中看到了这种行为。似乎进程越活跃,它对不同 CPU 的变化就越多。
我观察这种行为top
。我添加该Last Used Cpu
列。然后,即使进程 ID 保持不变,我也会观察到有趣的进程不断更改为不同的 CPU。
它的变化如此之大,以至于我相信我在某些作业上看到了不一致的性能,因为这些进程经常在同一 CPU 上暂时相互冲突,即使它们应该在覆盖作业运行时在不同的 CPU 之间保持平衡。当这些作业运行时,除了这些进程之外,服务器大部分时间都是空闲的。因此,我希望作业 1 在一组 CPU 上启动进程,而作业 2 最终在另一组 CPU 上启动并停留在那里。
EC2 上的 Amazon Linux 2 内核 4.14.x
答案1
Linux 调度程序使用自然的 CPU 亲和性:出于性能原因,调度程序尝试尽可能长时间地将进程保留在同一 CPU 上。您可以在普通 Linux 系统中使用taskset
.
但是,据我了解,除非您有专用实例,否则在 EC2 上将会存在大量 CPU 共享。您也许能够将进程与 vCPU 绑定在一起,但这只是表面功夫。
答案2
您使用 top 编写了观察该现象的方法。我不确定它是适合您分析的工具,因为正如 man top 所承认的那样:
- P — 最后使用的 CPU (SMP) 代表最后使用的处理器的数字。在真正的 SMP 环境中,这可能会频繁更改,因为内核有意使用弱关联性。此外,运行 top 的行为本身可能会破坏这种弱关联性,并导致更多进程更频繁地更换 CPU(因为对 cpu 时间有额外的需求)。
我个人更喜欢依赖 /proc/interrupts 中报告的重新调度中断计数。
答案3
即使当重叠的作业正在运行时,它们应该在不同的 CPU 之间保持平衡
不,他们不应该。您没有说您正在使用哪个调度程序,但据我所知,当前所有主流发行版默认都使用完全公平的调度程序。这将根据可用的 CPU 将任务分配给 CPU - 进程最后使用的 CPU 是首选目标,接下来是同一个超线程组中的 CPU,然后是同一个套接字上的 CPU(共享同一个 L2 缓存 IIRC?) - 然后当您处理 NUMA 时,事情开始变得复杂。如果你去寻找的话,它都记录在互联网上。
在一台快乐的机器上,进程在 CPU 上运行的可用最大时隙将不会达到 - 任务将执行某些操作,这意味着它必须等待某些事情发生,从而让出其位置。当平均负载接近 CPU 数量时,就会出现 CPU 资源争用,调度程序将在任务准备就绪之前开始将任务从 CPU 中踢出(它们被抢占)。通常这会稍微降低系统的吞吐量。
可以调整一些用于对 CPU 亲和性算法进行加权的系数。运行sysctl -A | grep "sched" | grep -v "domain"
查看参数。但请注意,在某种程度上,内核会在运行时调整 CFS。
当这些作业运行时,除了这些进程之外,服务器大部分处于空闲状态
真的吗?这些进程不执行任何网络或存储 I/O?