gpt4 book ai didi

c++ - CPU使用率高的常见原因是什么?

转载 作者:IT老高 更新时间:2023-10-28 22:23:29 35 4
gpt4 key购买 nike

背景:

在我用 C++ 编写的应用程序中,我创建了 3 个线程:

  • AnalysisThread(或生产者):它读取输入文件,解析它,生成模式,并将它们排入std::queue1
  • PatternIdRequestThread(或消费者):它从队列中提取模式,并通过客户端(用 C++ 编写)将它们一一发送到数据库,客户端返回模式 uid 然后分配到相应的模式。
  • ResultPersistenceThread :它只做一些事情,与数据库对话,并且就 CPU 使用率而言,它可以正常工作。

前两个线程占用 60-80% 的 CPU 使用率,每个线程平均占用 35%。

问题:

我不明白为什么有些线程占用高 CPU 使用率。

我分析如下:如果是操作系统做出像 context-switch 这样的决定, interrupt , 和 scheduling至于应该让哪个线程访问系统资源,例如 CPU 时间,那么为什么进程中的 一些 线程碰巧比其他线程使用更多的 CPU?看起来一些线程强行从操作系统中获取CPU在 Guzzle ,或者操作系统对某些线程有一个真正的软肋,所以它从一开始就偏向于它们,给他们所有的资源。为什么不能不偏不倚,一视同仁?

我知道这很幼稚。但是如果我沿着这条思路思考,我会更加困惑:操作系统根据线程要完成的工作量授予对 CPU 的访问权限,但是操作系统如何计算或预测工作量 在完全执行之前

我想知道 CPU 使用率高的原因是什么?我们如何识别它们?是否可以仅通过查看代码来识别它们?工具是什么?

我正在使用 Visual Studio 2010。

1.我对 std::queue 也有疑问。我知道标准容器不是线程安全的。但是,如果正好有一个线程将项目排入队列,那么如果只有一个线程将项目从其中排入队列是否安全?我想它就像一个管道,一方面你插入数据,另一方面你删除数据,那么如果它同时完成为什么会不安全呢?但这不是本主题的真正问题,但是,您可以在答案中添加注释来解决这个问题。

更新:

在我意识到我的消费者线程正在使用我已用 Sleep 修复的忙自旋之后3 秒。此修复是临时的,很快我将使用 Event反而。但即使是 Sleep ,CPU 使用率已下降到 30-40%,偶尔会上升到 50%,从可用性的角度来看,这似乎并不理想,因为系统不会响应用户使用的其他应用程序目前正在合作。

还有什么方法可以改善 CPU 使用率高的问题吗?如前所述,生产者线程(现在使用大部分 CPU 周期)读取文件,解析其中的数据包(某种格式),并从中生成模式。如果我使用 sleep ,那么 CPU 使用率会降低,但这是个好主意吗?常见的解决方法有哪些?

最佳答案

就我个人而言,如果我的线程有工作要做,而且我的机器上有空闲的内核,因为操作系统没有给它们高 CPU 使用率,我会非常恼火。所以我真的不认为这里有任何问题[编辑:原来你的繁忙循环是一个问题,但原则上高 CPU 使用率没有什么问题]。

操作系统/调度程序几乎无法预测线程将执行的工作量。线程(过度简化)处于以下三种状态之一:

  1. 阻塞等待某事( sleep 、互斥锁、I/O 等)
  2. 可运行,但当前未运行,因为其他东西在运行
  3. 正在运行。

调度程序将选择尽可能多的东西来运行它的核心(或超线程,等等),并运行每一个,直到它阻塞或直到称为“时间片”的任意时间段到期。如果可以的话,它会安排其他的事情。

因此,如果一个线程将大部分时间用于计算而不是阻塞,并且如果有一个内核空闲,那么它将占用大量 CPU 时间。

如何调度程序根据优先级等因素选择要运行的内容有很多细节。但基本思想是,一个有很多事情要做的线程不需要被预测为计算量大,只要有事情需要调度,它总是可用的,因此往往会被调度。

对于您的示例循环,您的代码实际上并没有做任何事情,因此在判断 5-7% 的 CPU 是否有意义之前,您需要检查它是如何优化的。理想情况下,在两核机器上,处理繁重的线程应该占用 50% 的 CPU。在 4 核机器上,25%。因此,除非您至少有 16 个内核,否则您的结果乍一看是异常的(如果您有 16 个内核,那么一个线程占用 35% 将更加异常!)。在标准桌面操作系统中,大多数内核大部分时间都处于空闲状态,因此实际程序在运行时占用的 CPU 比例越高越好。

在我的机器上,当我运行主要用于解析文本的代码时,我经常会占用一个内核的 CPU 使用率。

if exactly one thread enqueue items to queue, then is it safe if exactly one thread deque items from it?

不,这对于带有标准容器的 std::queue 是不安全的。 std::queue 是序列容器(vectordequelist)顶部的薄包装器,它不会增加任何线程安全性。添加项目的线程和删除项目的线程共同修改一些数据,例如底层容器的 size 字段。您需要一些同步,或者依赖于对公共(public)数据的原子访问的安全无锁队列结构。 std::queue 两者都没有。

关于c++ - CPU使用率高的常见原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9275262/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com