考虑以下循环:
for i in range(20):
if i == 10:
subprocess.Popen(["echo"]) # command 1
t_start = time.time()
1+1 # command 2
t_stop = time.time()
print(t_stop - t_start)
“命令2”在“命令1”之前运行时,系统地运行“命令2”需要更长的时间。下面的图显示了1+1
的执行时间,它是循环索引i
的函数,平均运行100次。在
前面加subprocess.Popen
时,1+1
的执行速度慢30倍。
更奇怪的是。人们可能认为只有subprocess.Popen()
之后运行的第一个命令受到影响,但事实并非如此。下面的循环显示当前循环迭代中的所有命令都会受到影响。但随后的循环迭代似乎基本上是正常的。在
下面是此循环的执行时间图,平均运行100次以上:
更多备注:
time.time()
引起的,因为它在timeit.timeit()
中是可见的,甚至在{subprocess.Popen
)和“command2”之间执行了许多不同的(可能占用CPU和内存)操作,也会发生这种情况。在arr += 1
操作可能需要300毫秒!在问题:什么可能导致这种效果,为什么它只影响当前循环迭代?在
我怀疑这可能与上下文切换有关,但这似乎不能解释为什么整个循环迭代会受到影响。如果上下文切换确实是原因,为什么有些命令会触发它,而另一些则不会呢?在
我的猜测是,这是由于Python代码被从CPU/内存系统中的各种缓存中逐出所致
perflib
包可用于提取有关缓存状态(即命中/未命中数)的更详细的CPU级统计信息。在在
Popen()
调用之后,我得到LIBPERF_COUNT_HW_CACHE_MISSES
计数器的~5倍:给我:
^{pr2}$(在非标准位置断行表示代码流)
相关问题 更多 >
编程相关推荐