它有助于了解 CPU 是如何工作的,以找出发生这种情况的原因。我将通过谈论只有一个核心的 CPU 来简化它,对于具有多个核心的 CPU,故事不会改变。
一个 CPU 内核在不处于睡眠模式时只能处于两种不同的状态。它要么正在执行代码,要么以执行指令的最快速度全速运行。或者它没有执行代码,因为不需要做任何事情。在这种情况下,它会被物理关闭。当它执行 HLT 指令时会发生这种情况。停下来,什么都不做,不消耗能量。
只有一种方法可以使处理器从 Halt 状态中恢复,即需要中断。那是芯片上的一个物理引脚,该引脚上的电压会使其恢复活力。该电压是由一个中断控制器产生的,另一个芯片接收来自机器各个部分的请求,以让 CPU 做一些有用的事情。
该中断的最重要来源是时钟。它以 0.0156 秒滴答作响,每秒使 CPU 恢复活力 64 次。这会激活操作系统中的一段代码,该代码基本上检查两件事。“我睡着的时候发生什么事了吗?” 并且“我根本没有睡着,是时候做一些其他也很重要的事情了”。或者换句话说,它不只是让 cpu 活跃起来,它还会打断它正在做的事情。因此信号的名称。
时钟不是唯一的中断源,CPU 上还有其他硬件。输入/输出设备。任何机器都有的重要部件是磁盘控制器、光驱控制器、网卡、鼠标和键盘。以及您在设备管理器小程序中看到的任何其他内容。它们是具有自己的小处理器的子系统,可以处理事情。并告诉主cpu他们已经完成了。因此,您机器上等待结果的任何线程都可以使用提供的数据继续执行。
大多数时候,你身边的那台个人电脑并没有做任何重要的事情。比如说,等待你阅读这个答案。由视频适配器和液晶显示器负责的东西,cpu 不必帮忙。您可以在 TaskMgr.exe 中看到它,cpu 利用率在 0 附近徘徊。您移动鼠标,单击滚动条以阅读此(长)答案,然后发生了一些事情。鼠标会产生一个中断,该中断会通过几层软件,最终告诉浏览器滚动视图。这需要大约几毫秒,给予或接受。
几毫秒的工作后,cpu 马上又睡着了。因此,当您通过性能计数器向 CPU 询问“您最近做了多少工作”时,它会说:“好吧,我花了几毫秒的时间来燃烧核心并竭尽全力更新您的屏幕。但是没有,其他比我睡在豌豆上”
所以重要的是你问的频率。样板方式是 Perfmon 使用的方式。它每秒问一次“你做了什么”。处理器会说:“好吧,在最后一秒,我执行了 20 毫秒的有用工作。其余时间我都死了,没有什么有用的事情可做”。所以任务管理器显示2%。
现在让我们按照你的方式去做吧。您要求 perf 计数器值,然后一纳秒后您再次要求它。处理器会说:“好吧,我返回了一个性能计数器值并试图回到睡眠状态。没有工作,程序一直在运行代码并问我同样的事情!”。
所以结果是准确的,处理器被你的请求占用了,你没有给它关机的机会。CPU 利用率为 100%。
解决方案:像 Perfmon 那样做。用计时器询问一次。让它更短,数字上升和下降更快。让它太短,它将是 100%