Python中更复杂的并行forloop

2024-06-16 10:22:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个非常耗时的循环,我想通过并行化来加速。在

for y in range(0, 288):
    for x in range(0, 352):
        w0=Waves.GetSampleValues(Waves.WaveParams((a0[y, x], 0, p0[y, x], 0)))
        w1=Waves.GetSampleValues(Waves.WaveParams((a1[y, x], 0, p1[y, x], 0)))

        am0, am1, ph0, ph1=DemodPoint(w0, w1, useOld)
        resultPhase0[y, x]=ph0
        resultPhase1[y, x]=ph1
        resultAmp0[y, x]=am0
        resultAmp1[y, x]=am1
    print("Y: ", y)
return resultAmp0, resultAmp1, resultPhase0, resultPhase1

每个像素都可以独立计算,所以理论上应该没有问题。 我已经找到了http://pythonhosted.org/joblib/parallel.html,它似乎能够解决这样的问题,但是我没有这样的生成器表达式。在

如您所见,我有多个结果数组需要填充(其中DemodPoint调用,它一次返回所有内容是代价高昂的部分),这似乎不适合这种结构。在

在页面的下面有一个更复杂的例子,它使用临时文件,但我实际上尽量让事情变得简单。类似于C++中的OpenMP,我想说“只要并行执行,我知道它会工作”,而不需要额外的代码。在python中,什么是最简单的方法呢?在


Tags: inforrangew1wavesw0ph1am1
1条回答
网友
1楼 · 发布于 2024-06-16 10:22:07

multiprocessing模块可以非常优雅地处理这个问题。将源数据复制到每个工作进程都会产生一些开销,因此可能有一种更有效的方法来处理此问题(例如,通过编写自己的worker类),但这应该是可行的。在

在池.map只能使用单个参数调用worker fn,但可以通过将所有输入打包到单个元组中来解决此问题:

import multiprocessing

...

def calc_one(xymm):
  x,y,(a0,p0,a1,p1) = xymm
  w0 = Waves.GetSampleValues(Waves.WaveParams((a0[y, x], 0, p0[y, x], 0)))
  w1 = Waves.GetSampleValues(Waves.WaveParams((a1[y, x], 0, p1[y, x], 0)))

  return x,y,DemoPoint(w0, w1, useOld)

inputs = []
for y in range(0, 288):
  for x in range(0, 352):
    inputs.append((x,y,(a0,p0,a1,p1)))

resultPhase0 = {}
resultPhase1 = {}
resultAmp0 = {}
resultAmp1 = {}

num_of_workers = multiprocessing.cpu_count()
pool = multiprocessing.Pool(num_of_workers)

for data in pool.map(calc_one,inputs):
  x,y,(am0,am1,ph0,ph1) = data
  resultPhase0[y,x],resultPhase1[y,x],resultAmp0[y,x],resultAmp1[y,x] = ph0,ph1,am0,am1

return resultAmp0, resultAmp1, resultPhase0, resultPhase1

当然,对于更大的数据集,您可能希望在滚动的基础上对作业结果进行排队和处理,而不是像池.map是的-我只是在用池.map这里的例子非常简单。多处理文档有一些很好的例子。在

相关问题 更多 >