CPU 百分比和繁重的多线程

Posted

技术标签:

【中文标题】CPU 百分比和繁重的多线程【英文标题】:CPU percentage and heavy multi-threading 【发布时间】:2019-06-24 09:19:15 【问题描述】:

我观察到 CPU 百分比的奇怪影响,例如Linux (Ubuntu 16.04) 上的 top 或 htop 用于一个特殊应用程序。该应用程序使用许多线程(大约 1000 个)。每个线程都有一个计算任务。这些任务中大约有一半需要每个“触发器”计算一次——触发器是每 100 毫秒准确接收一次的外部事件。其他线程大多处于休眠状态(等待用户交互),因此在这里没有发挥重要作用。总结一下:许多线程在很短的时间内基本上同时唤醒,在那里进行(相对较短的)计算并再次进入睡眠状态。

由于运行此应用程序的机器有 8 个虚拟 CPU(4 核每 2 个线程,它是 i7-3612QE),因此一次只能真正唤醒 8 个线程,因此需要等待很多线程。此外,其中一些任务具有相互依赖性,因此它们无论如何都必须等待,但我认为可以将这个应用程序视为一组线程,每 100 毫秒同时进入可运行状态,每个线程只进行一次短计算(每个 CPU 时间都低于 1 毫秒)。

现在出现奇怪的效果:如果我查看“top”中的 CPU 百分比,它会显示大约 250%。据我所知,top 查看内核占该进程的 CPU 时间(用户 + 系统),因此 250% 意味着该进程平均使用 3 个虚拟 CPU。到现在为止还挺好。现在,如果我使用 taskset 强制整个进程只使用单个虚拟 CPU,CPU 百分比下降到 80%。该应用程序具有内部会计,它告诉我仍在处理所有数据。因此,应用程序正在执行相同数量的工作,但它使用的 CPU 资源似乎更少。怎么可能?我真的可以相信内核 CPU 时间统计吗,或者这是测量的假象?

如果我启动其他占用大量 CPU 的进程,即使什么都不做(“while(true);”)并且以低优先级运行(很好),CPU 百分比也会下降。如果我启动 8 个占用 CPU 的进程,应用程序将再次达到 80%。随着 CPU 消耗者的减少,我的 CPU% 会逐渐提高。

不确定这是否起作用:我使用了分析器 vtune,它告诉我我的应用程序实际上效率很低(只有大约 1 个 IPC),主要是因为它受内存限制。如果我将进程限制为单个虚拟 CPU,这不会改变,因此我假设在同一内核上运行所有内容时效率不会大幅提高(无论如何这会很奇怪)。

【问题讨论】:

多核设置中系统时间/用户时间/等待时间的比例是多少?在单核设置中? @gudok 如何找出进程的等待时间?据我所知,/proc/pid/stat 仅提及系统和用户时间......如果我将进程强制在单个核心上而不是在所有核心上运行,系统与用户时间的比率大致保持不变。 【参考方案1】:

我的问题在最后一段中基本上已经由我自己回答了:这个过程是内存绑定的。因此,不是 CPU 是有限的资源,而是内存带宽。允许这样的进程在多个 CPU 内核上并行运行主要会产生更多 CPU 内核正在等待数据从 RAM 到达的效果。这算作 CPU 负载,因为 CPU 正在执行线程,但速度非常慢。我的所有其他观察都与此一致。

【讨论】:

以上是关于CPU 百分比和繁重的多线程的主要内容,如果未能解决你的问题,请参考以下文章

如何实现令牌系统以限制 C# 中处理器/IO 繁重的多线程任务的并发性?

为什么python的多线程不能利用多核CPU,但是咱们在写代码的时候,多线程的确是在并发,而且还比单线程快。

python的多线程为什么不能利用多核CPU?

现代 CPU 中的多线程旧遗留应用程序 [关闭]

我的多线程游戏一直处于 100% CPU。如何管理线程活动以减少 CPU 负载?

为啥 C# 中的多线程不能达到 100% CPU?