【发布时间】:2015-07-17 15:44:12
【问题描述】:
原始问题
我正在尝试在 Python 中使用多处理池。这是我的代码:
def f(x):
return x
def foo():
p = multiprocessing.Pool()
mapper = p.imap_unordered
for x in xrange(1, 11):
res = list(mapper(f,bar(x)))
当xrange 像xrange(1, 6) 一样小时,此代码会使用所有 CPU(我有 8 个 CPU)。但是,当我将范围增加到xrange(1, 10) 时。我观察到只有 1 个 CPU 以 100% 的速度运行,而其余的只是空闲。可能是什么原因?是不是因为当我增加范围时,操作系统会因为过热而关闭 CPU?
我该如何解决这个问题?
最小的、完整的、可验证的例子
为了复制我的问题,我创建了这个例子:Its a simple ngram generation from a string problem。
#!/usr/bin/python
import time
import itertools
import threading
import multiprocessing
import random
def f(x):
return x
def ngrams(input_tmp, n):
input = input_tmp.split()
if n > len(input):
n = len(input)
output = []
for i in range(len(input)-n+1):
output.append(input[i:i+n])
return output
def foo():
p = multiprocessing.Pool()
mapper = p.imap_unordered
num = 100000000 #100
rand_list = random.sample(xrange(100000000), num)
rand_str = ' '.join(str(i) for i in rand_list)
for n in xrange(1, 100):
res = list(mapper(f, ngrams(rand_str, n)))
if __name__ == '__main__':
start = time.time()
foo()
print 'Total time taken: '+str(time.time() - start)
当num 很小(例如num = 10000)时,我发现所有 8 个 CPU 都被使用了。然而,当num 相当大时(例如num = 100000000)。仅使用了 2 个 CPU,其余 CPU 处于空闲状态。这是我的问题。
警告:当num 太大时,可能会导致系统/VM 崩溃。
【问题讨论】:
-
bar返回什么? -
bar返回一个igraph对象,x确定图形的深度。会不会有影响? -
如果
igraph足够大,与实际工作相比,它可能会花费更多时间来酸洗参数和结果并将它们推过管道(尤其是工作只是return x!),它肯定会将所有内容序列化到一个CPU。当然,深度 5 的图形不会出现这个问题,但深度 9 的图形会出现这个问题。 -
你能给我们一个minimal, complete, verifiable example 有一些好的假数据吗?然后我们也许可以分析和/或测试它,而不必猜测。
-
好吧,这绝对是我的想法。您将大约 75% 的时间花在为排队而战,将 25% 的时间花在
multiprocessing开销上,而将 0% 的时间花在实际工作上。在 2.7 中,开销是序列化的,所以一切都发生在一个核心上。在 3.4 中,开销是并行化的,因此您的其他内核有一些工作要做,但这仍然只是开销(无用的工作)。
标签: python multiprocessing pool