多处理比python顺序慢

时间:2015-03-10 10:42:22

标签: python multiprocessing

我已经投入了大量时间来重写我的代码以利用更多内核,但是当我对其进行基准测试时,我发现我所做的就是使其比原始代码慢7倍,尽管运行时间为16核心而不是一个!这让我相信我一定做错了。

代码是4000多行,需要大量非常繁重的输入文件,因此我无法发布可以重现问题的内容。但是,我可以说我调用的函数通常需要0.1秒来运行并使用ctypes调用一些c库。它还在内存中传递了相当数量的数据 - 可能是1 MB?一些看起来像慢位的伪代码:

    def AnalyseSection(Args):
        Sectionsi,SectionNo,ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq=Args
        for i in range(len(Sections[Elements])):
           #Do some heavy lifting with ctypes
        return Result

     for i in range(10):
         for j in range(10):
             for k in range(10):
                 Args=[(Sections[i],SectionList[i],ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq) for n in SectionList]
                 pool=mp.Pool(processes=NoCPUs,maxtasksperchild=1)
                 result = pool.map(AnalyseSection,Args)
                 pool.close()
                 pool.join()

我希望有人能发现一个明显的错误,导致它运行得如此之慢?该函数需要一段时间才能运行(通常每次调用0.1秒),因此我认为与多处理相关的开销可能会减慢这么多。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

这个

 for i in range(10):
     for j in range(10):
         for k in range(10):
             Args=[(Sections[i],SectionList[i],ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq) for n in SectionList]
             pool=mp.Pool(processes=NoCPUs,maxtasksperchild=1)
             result = pool.map(AnalyseSection,Args)
             pool.close()
             pool.join()

可以而且应该转换为此

 pool=mp.Pool(processes=NoCPUs)

 for i in range(10):
     for j in range(10):
         for k in range(10):
             Args=[(Sections[i],SectionList[i],ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq) for n in SectionList]
             result = pool.map(AnalyseSection,Args)

 pool.join()

这更符合您要实现的目标。您有一个多处理池,您可以在其中提供数据并等待结果。您不必在每次迭代中启动/停止池。

请记住,开始处理会产生相关成本(如果您习惯使用线程,则比线程大得多)。