问题是你正在使用哑元。即多线程,而不是多处理。多线程不会使CPU绑定的任务更快,但只有I/O绑定的任务。
再试一次multiprocessing.Pool,你应该有更多的成功。
multiprocessing.dummy in Python is not utilising 100% cpu
你也需要以某种方式块你输入序列到子序列,以做好每一道工序做足够的计算方法,这是值得的。
我把这个解决方案。看到你只需要在主执行时调用多处理池,问题是Python会启动执行每个映射的子引擎。
import time
from multiprocessing import Pool as ThreadPool
def square(x):
return x*x
def squareChunk(chunk):
return [square(x) for x in chunk]
def chunks(l, n):
n = max(1, n)
return (l[i:i+n] for i in range(0, len(l), n))
def flatten(ll):
lst = []
for l in ll:
lst.extend(l)
return lst
if __name__ == '__main__':
start_time = time.time()
r1 = range(10000000)
nProcesses = 100
chunked = chunks(r1, int(len(r1)/nProcesses)) #split original list in decent sized chunks
pool = ThreadPool(4)
results = flatten(pool.map(squareChunk, chunked))
pool.close()
pool.join()
print("--- Parallel map %g seconds ---" % (time.time() - start_time))
start_time = time.time()
r2 = range(10000000)
squareChunk(r2)
print("--- Serial map %g seconds ---" % (time.time() - start_time))
我碰到下面的打印输出:
--- Parallel map 3.71226 seconds ---
--- Serial map 2.33983 seconds ---
现在的问题是不应该的并行地图更快?
这可能是整个组块会影响我们的效率。但是也可能是当串行处理运行后引擎更“热身”。于是我转身测量:
import time
from multiprocessing import Pool as ThreadPool
def square(x):
return x*x
def squareChunk(chunk):
return [square(x) for x in chunk]
def chunks(l, n):
n = max(1, n)
return (l[i:i+n] for i in range(0, len(l), n))
def flatten(ll):
lst = []
for l in ll:
lst.extend(l)
return lst
if __name__ == '__main__':
start_time = time.time()
r2 = range(10000000)
squareChunk(r2)
print("--- Serial map %g seconds ---" % (time.time() - start_time))
start_time = time.time()
r1 = range(10000000)
nProcesses = 100
chunked = chunks(r1, int(len(r1)/nProcesses)) #split original list in decent sized chunks
pool = ThreadPool(4)
results = flatten(pool.map(squareChunk, chunked))
pool.close()
pool.join()
print("--- Parallel map %g seconds ---" % (time.time() - start_time))
现在我得到:
--- Serial map 4.176 seconds ---
--- Parallel map 2.68242 seconds ---
所以它不是那么清楚一方或另一方是否更快。但是如果你想做多处理,你必须考虑创建线程的开销实际上是否比你期望的更快。你碰到缓存局部性问题等。
https://wiki.python.org/moin/GlobalInterpreterLock – niemmi
另外,你不是多处理,你是multi_threading_。 '多。dummy'只是线程库的一个包装。 https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.dummy。这就是GIL与此相关的原因。 –
@niemmi嗯,但这是我创建的一个过程,而不是一个线程。纠正我,如果我错了。 GIL在您创建多个线程时适用。就我所知,多个进程可以在python中使用多个内核。 – Rishabh