繁体   English   中英

为什么我的并行代码比顺序代码慢

[英]Why my parallel code is slower than the sequential

我正在尝试实现一种高度可并行化的在线递归并行算法。 我的问题是我的python实现不能正常工作。 我有两个2D矩阵,我希望每次在时间步t观察到新观察时,每列都递归更新。 我的并行代码是这样的

def apply_async(t):
    worker =  mp.Pool(processes = 4)
    for i in range(4):
        X[:,i,np.newaxis], b[:,i,np.newaxis] =  worker.apply_async(OULtraining, args=(train[t,i], X[:,i,np.newaxis], b[:,i,np.newaxis])).get()


    worker.close()
    worker.join()      




for t in range(p,T):
    count = 0 
    for l in range(p):
        for k in range(4):
            gn[count]=train[t-l-1,k]
            count+=1
    G = G*v +  gn @ gn.T
    Gt = (1/(t-p+1))*G

    if __name__ == '__main__':
        apply_async(t)

两个矩阵是X和b。 我想直接替换master的内存,因为每个进程只递归更新矩阵的一个特定列。

为什么这个实现比顺序慢?

有没有办法在每个时间步骤恢复该过程而不是杀死它们并再次创建它们? 这可能是它变慢的原因吗?

原因是,您的程序在实践中是顺序的。 这是一个与您的并行性立场相同的示例代码段:

from multiprocessing import Pool
from time import sleep

def gwork( qq):
    print (qq)
    sleep(1)
    return 42

p = Pool(processes=4)

for q in range(1, 10):
    p.apply_async(gwork, args=(q,)).get()
p.close()
p.join()

运行此操作,您会发现1-9号码恰好出现在一秒钟内。 为什么是这样? 原因是你的.get() 这意味着每次调用apply_async都会在get()中实际阻塞,直到结果可用。 它将提交一个任务,等待一秒仿真处理延迟,然后返回结果,之后将另一个任务提交给您的池。 这意味着根本没有并行执行。

尝试用以下方法替换池管理部分:

results = []
for q in range(1, 10):
    res = p.apply_async(gwork, args=(q,))
    results.append(res)
p.close()
p.join()
for r in results:
    print (r.get())

您现在可以在工作中看到并行性,因为现在可以同时处理四个任务。 你的循环不会阻塞get,因为get被移出循环,结果仅在它们准备好时才被接收。

注意:如果你的工作者的参数或它们的返回值是大数据结构,你将失去一些性能。 在实践中,Python将这些实现为队列,并且相对于在子进程分叉时获取数据结构的内存中副本而相对而言,通过队列传输大量数据的速度较慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM