好的,这是我的问题:我的程序中有一个嵌套的for循环,它运行在一个核心上。由于程序在这个嵌套的for循环中花费了超过99%的运行时间,我想并行化它。现在我必须等待9天才能完成计算。我尝试使用multiprocessing
库实现并行for循环。但我只找到非常基本的例子,不能将它们转移到我的问题上。以下是具有随机数据的嵌套循环:
import numpy as np
dist_n = 100
nrm = np.linspace(1,10,dist_n)
data_Y = 11000
data_I = 90000
I = np.random.randn(data_I, 1000)
Y = np.random.randn(data_Y, 1000)
dist = np.zeros((data_I, dist_n)
for t in range(data_Y):
for i in range(data_I):
d = np.abs(I[i] - Y[t])
for p in range(dist_n):
dist[i,p] = np.sum(d**nrm[p])/nrm[p]
print(dist)
请给我一些建议如何使其平行。
答案 0 :(得分:1)
启动进程(50ms +取决于数据大小)的开销很小,因此通常最好能够获得最大的代码块。从您的评论中可以看出,t
的每个循环都是独立的,因此我们可以自由地将其并行化。
当python创建一个新进程时,您将获得主进程的副本,以便您可以获得所有全局数据,但是当每个进程写入数据时,它会写入自己的本地副本。这意味着dist[i,p]
对主进程无法使用,除非您使用返回显式传回(这会产生一些开销)。在您的情况下,如果每个进程将dist[i,p]
写入文件,那么您应该没问题,除非您实现某种类型的互斥锁访问控制,否则不要尝试写入同一文件。
#!/usr/bin/python
import time
import multiprocessing as mp
import numpy as np
data_Y = 11 #11000
data_I = 90 #90000
dist_n = 100
nrm = np.linspace(1,10,dist_n)
I = np.random.randn(data_I, 1000)
Y = np.random.randn(data_Y, 1000)
dist = np.zeros((data_I, dist_n))
def worker(t):
st = time.time()
for i in range(data_I):
d = np.abs(I[i] - Y[t])
for p in range(dist_n):
dist[i,p] = np.sum(d**nrm[p])/nrm[p]
# Here - each worker opens a different file and writes to it
print 'Worker time %4.3f mS' % (1000.*(time.time()-st))
if 1: # single threaded
st = time.time()
for x in map(worker, range(data_Y)):
pass
print 'Single-process total time is %4.3f seconds' % (time.time()-st)
print
if 1: # multi-threaded
pool = mp.Pool(28) # try 2X num procs and inc/dec until cpu maxed
st = time.time()
for x in pool.imap_unordered(worker, range(data_Y)):
pass
print 'Multiprocess total time is %4.3f seconds' % (time.time()-st)
print
如果再次增加data_Y / data_I的大小,加速应该增加到理论极限。