我已经用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)
目前没有回答
相关问题 更多 >
编程相关推荐