问题描述
我已经使用psutil
用Python编写了性能监控器功能,以测量cpu,GPU和磁盘I / O,以对另一个应用程序进行基准测试。在我最初的测试中,它工作得很好,但是当它接近100%时,我发现它严重低估了cpu使用率。我正在寻求帮助,以找出发生这种情况的原因。
该功能似乎过于复杂,但是我试图做两件事:实时显示当前用法;并在最后报告最高的5秒滚动平均值。这是因为我无法预测子流程将花费多长时间,并且我想消除短期波动。
下面是该函数的简化版本。在此示例中,我删除了所有GPU和磁盘度量,并对打印语句作了一些改动以进行调试。尽管我尝试每秒采样一次,但我发现elapsed
时间有时会在cpu使用率很高时波动高达1.8。
这是在Windows 10上运行的。任务管理器显示的cpu使用率恒定为100%,没有波动,如果我在另一个也显示100%的窗口中运行psutil.cpu_times_percent()
,则此处的功能显示为大约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)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)