python - 为什么 psutil CPU 使用率太低?
问题描述
我用 Python 编写了一个性能监视器函数,psutil
用于测量 CPU、GPU 和磁盘 I/O,以对另一个应用程序进行基准测试。它在我最初的测试中运行良好,但我发现它在接近 100% 时显着低估了 CPU 使用率。我正在寻求帮助,弄清楚为什么会发生这种情况。
这个功能可能看起来过于复杂,但我正在尝试做两件事:实时显示当前使用情况;并在最后报告最高的 5 秒滚动平均值。这是因为我无法预测子流程需要多长时间,并且我想消除短期波动。
该函数的简化版本如下。在此示例中,我删除了所有 GPU 和磁盘测量,并稍微更改了打印语句以进行调试。尽管我尝试每秒采样一次,但elapsed
有时当 CPU 使用率非常高时,时间波动高达 1.8。
这是在 Windows 10 上运行的。任务管理器显示恒定的 100% CPU 使用率,没有波动,如果我psutil.cpu_times_percent()
在另一个也显示 100% 的窗口中运行,而我的功能显示大约 90%。
import psutil
import time
import shlex
import subprocess
from concurrent.futures import ThreadPoolExecutor
def perf_monitor(proc):
# measure CPU, GPU, and Disk R/W every 1 seconds, and calculate a rolling average every 5 seconds
# return the maximum of each rolling average
rolling_interval = 5
sample_interval = 1
rolling_samples = []
stats = {
'cpu': 0,
}
cpu_count = psutil.cpu_count()
while True: # loop until subprocess is finished
# reset starting values
start = time.time()
cpu1 = psutil.cpu_times()
cpu1 = cpu1.user + cpu1.system
# measure again after the interval
time.sleep(sample_interval)
cpu2 = psutil.cpu_times()
cpu2 = cpu2.user + cpu2.system
# list starts at zero and counts up, then remains at 5
elapsed = time.time() - start # may be slightly longer than sample_interval
rolling_samples.append({
'cpu': (cpu2 - cpu1) / cpu_count / elapsed,
})
# skip reporting for the first 5 seconds warm up
if len(rolling_samples) < rolling_interval:
continue
# get the rolling average over a defined interval (5 seconds)
rolling_avg_cpu = sum([sample['cpu'] for sample in rolling_samples]) / rolling_interval
print([sample['cpu'] for sample in rolling_samples], elapsed) # for debugging
print(f"CPU: {rolling_avg_cpu:.1%} ", end='\n',)
# update each stat only if it has increased
if rolling_avg_cpu > stats['cpu']:
stats['cpu'] = rolling_avg_cpu
# remove oldest sample so we always keep 5
del rolling_samples[0]
# return stats when render is finished
if proc.poll() is not None:
return stats
if __name__ == "__main__":
command = '"MyApp.exe'
with ThreadPoolExecutor() as executor:
proc = subprocess.Popen(shlex.split(command))
thread = executor.submit(perf_monitor, proc)
stats = thread.result()
print(stats)
解决方案
推荐阅读
- java - 从 CSV 读取列并保存到列表中
- > 在Java中
- python - 从下面的单元格中减去 2 个字符串,分别对应 pandas 中的索引或客户 ID
- laravel - 在 Laravel 上使用 firstOrCreate 时出现重复条目?
- image - 在 pytorch 中加载 csv 和 Image 数据集
- excel - HRESULT 异常:0x800A03EC excel.range
- python - Google Colab 无法提取保存在我的 Google 云端硬盘中的大文件
- javascript - 如何将js变量添加到表单中?
- excel - Excel - 如何根据三个字段(过滤器)计算列
- c++ - 在具有 3v3 电源的芯片上检测来自 2v5 src 的数字输入?
- android - 我无法在 Android Studio 中访问“TextView”或“Button”