python 的多处理比顺序处理慢
Multiprocessing slower than sequential with python
我投入了大量时间来重写我的代码以利用更多内核,但是当我对其进行基准测试时,我发现我所取得的成就只是使它比原始代码慢 7 倍,尽管 运行宁在 16 个核心而不是一个!这让我相信我一定做错了什么。
代码超过 4000 行,需要大量的输入文件,所以我无法 post 重现问题。但是,我可以说我调用的函数通常需要 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.1s)所以我不认为与多处理相关的开销会减慢它的速度。任何帮助将不胜感激!
这个
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()
这更符合您要实现的目标。您有一个多处理池,您可以在其中提供数据并等待结果。您不必在每次迭代中 start/stop 池。
请记住,启动处理会产生一定的成本(如果您习惯使用线程,则成本比线程大得多)。
我投入了大量时间来重写我的代码以利用更多内核,但是当我对其进行基准测试时,我发现我所取得的成就只是使它比原始代码慢 7 倍,尽管 运行宁在 16 个核心而不是一个!这让我相信我一定做错了什么。
代码超过 4000 行,需要大量的输入文件,所以我无法 post 重现问题。但是,我可以说我调用的函数通常需要 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.1s)所以我不认为与多处理相关的开销会减慢它的速度。任何帮助将不胜感激!
这个
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()
这更符合您要实现的目标。您有一个多处理池,您可以在其中提供数据并等待结果。您不必在每次迭代中 start/stop 池。
请记住,启动处理会产生一定的成本(如果您习惯使用线程,则成本比线程大得多)。