为什么在python3中,很小的检查间隔不会降低CPU密集型多线程的速度?
在阅读之后,我认为一个小的间隔将导致更多的线程睡眠/唤醒操作,然后总的执行时间应该更长。我错了吗 测试环境:四核Ubuntu16.04 python3.5。是的,你是对的。 较低的切换间隔意味着将有更频繁的针对GIL的条件轮询,以查看是否可以获得GIL。 由于GIL,我们无法并行运行线程,因此更频繁的上下文切换实际上会损害我们的性能为什么在python3中,很小的检查间隔不会降低CPU密集型多线程的速度?,python,python-3.x,cpython,gil,Python,Python 3.x,Cpython,Gil,在阅读之后,我认为一个小的间隔将导致更多的线程睡眠/唤醒操作,然后总的执行时间应该更长。我错了吗 测试环境:四核Ubuntu16.04 python3.5。是的,你是对的。 较低的切换间隔意味着将有更频繁的针对GIL的条件轮询,以查看是否可以获得GIL。 由于GIL,我们无法并行运行线程,因此更频繁的上下文切换实际上会损害我们的性能 如果您想提高系统的性能,您必须使用解决方案。请注意,整个任务只需1秒左右。因此,如果开关间隔为0.001秒,那么总共只有大约1/0.001=1000个开关。每个开关
如果您想提高系统的性能,您必须使用解决方案。请注意,整个任务只需1秒左右。因此,如果开关间隔为0.001秒,那么总共只有大约1/0.001=1000个开关。每个开关的成本(以“C速度”发生)更自然地以微秒来衡量,而不是以毫秒来衡量,因此与总的1秒运行时间相比,一千个开关仍然便宜 要查看更多效果,请尝试将切换间隔设置为
1e-6
在现实生活中,线程切换的实际成本通常是相关的成本:一个线程获得足够的时间来填充硬件指令和数据缓存,然后被切换出去,新线程首先在不同级别上遭受缓存未命中。您的示例没有任何这些开销(每个线程使用的代码和数据相对较小,两个线程的内容甚至可以同时放在一级缓存中)
from threading import Thread
def countdown(start, end):
while end > start:
end -= 1
def multi_thread(n):
t1 = Thread(target=countdown, args=(0, n // 2))
t2 = Thread(target=countdown, args=(n // 2, n))
t1.start()
t2.start()
t1.join()
t2.join()
if __name__ == '__main__':
import timeit
import sys
sys.setswitchinterval(1)
print(timeit.timeit("""import gil;gil.multi_thread(10000000);""", number=1))
# 1.07s
sys.setswitchinterval(0.001)
print(timeit.timeit("""import gil;gil.multi_thread(10000000);""", number=1))
# 1.09s