【发布时间】:2016-01-23 15:10:30
【问题描述】:
假设我想并行化一些密集计算(不受 I/O 限制)。
当然,我不想运行比可用处理器更多的进程,否则我会开始为上下文切换(和缓存未命中)付费。
在心理上,我预计随着 n 在 multiprocessing.Pool(n) 中的增加,总时间会像这样:
- 任务利用并行化的负斜率
- 正斜率,因为上下文切换开始让我付出代价
- 高原
但实际上,我得到了这个:
#!/usr/bin/env python
from math import factorial
def pi(n):
t = 0
pi = 0
deno = 0
k = 0
for k in range(n):
t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k)
deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k))
pi += t/deno
pi = pi * 12/(640320**(1.5))
pi = 1/pi
return pi
import multiprocessing
import time
maxx = 20
tasks = 60
task_complexity = 500
x = range(1, maxx+1)
y = [0]*maxx
for i in x:
p = multiprocessing.Pool(i)
tic = time.time()
p.map(pi, [task_complexity]*tasks)
toc = time.time()
y[i-1] = toc-tic
print '%2d %ds' % (i, y[i-1])
import matplotlib.pyplot as plot
plot.plot(x, y)
plot.xlabel('Number of threads')
plot.xlim(1, maxx)
plot.xticks(x)
plot.ylabel('Time in seconds')
plot.show()
我的机器:i3-3217U CPU @ 1.80GHz × 4
操作系统:Ubuntu 14.04
在 n>4 之后,我看到任务管理器在各个进程中循环,正如预期的那样,因为进程多于处理器。然而,相对于 n=4(我的处理器数量)没有任何惩罚。
事实上,即使在 n
我在使用 gnome-system-monitor 时看到了这种行为:(如果有人有不同的体验,请告诉我。)
任何解释为什么我触发多少进程似乎并不重要?还是我的代码有问题?
我的猜测:似乎进程不受处理器限制(即使只有两个进程处于活动状态,它们也会不断切换 CPU),因此无论如何我都要为上下文切换付费。
参考资料:
编辑:用更高的常数更新了图形和代码。
【问题讨论】:
-
出于兴趣:您有多少个处理器线程可用?
-
@poke,我忘了提。 :) 我同时添加了这些信息和其他信息。
-
@mata 我会尽快报告。无论如何,如果有人可以在其他机器和操作系统中尝试这个,那也很有趣。我将验证一个类似的答案。
标签: python multithreading multiprocess