如何在python中并行化嵌套的for循环?

时间:2018-02-09 16:34:39

标签: python parallel-processing multiprocessing

好的,这是我的问题:我的程序中有一个嵌套的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)

请给我一些建议如何使其平行。

1 个答案:

答案 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的大小,加速应该增加到理论极限。