昨天我问了一个问题:Reading data in parallel with multiprocess
我得到了非常好的答案,我实施了答案中提到的解决方案,我标记为正确。
def read_energies(motif):
os.chdir("blabla/working_directory")
complx_ener = pd.DataFrame()
# complex function to fill that dataframe
lig_ener = pd.DataFrame()
# complex function to fill that dataframe
return motif, complx_ener, lig_ener
COMPLEX_ENERGIS = {}
LIGAND_ENERGIES = {}
p = multiprocessing.Pool(processes=CPU)
for x in p.imap_unordered(read_energies, peptide_kd.keys()):
COMPLEX_ENERGIS[x[0]] = x[1]
LIGAND_ENERGIES[x[0]] = x[2]
但是,此解决方案需要相同的时间,就像我只是迭代peptide_kd.keys()
并逐个填充DataFrames
一样。为什么会这样?有没有办法并行填写所需的dicts并实际上提高速度?我在48核HPC上运行它。
答案 0 :(得分:8)
在(1)启动每个进程,以及(2)必须在多个进程中复制pandas.DataFrame
(和等)时,会产生大量开销。如果您只需要并行填充dict
,我建议您使用共享内存dict
。如果没有密钥被覆盖,那么这很简单,您不必担心锁定。
(注意我正在使用下面的multiprocess
,这是multiprocessing
的一个分支 - 但只有我可以从解释器演示,否则,你必须从{ {1}})。
__main__
此解决方案不会复制>>> from multiprocess import Process, Manager
>>>
>>> def f(d, x):
... d[x] = x**2
...
>>> manager = Manager()
>>> d = manager.dict()
>>> job = [Process(target=f, args=(d, i)) for i in range(5)]
>>> _ = [p.start() for p in job]
>>> _ = [p.join() for p in job]
>>> print d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
以跨进程共享,因此可以减少部分开销。对于像dict
这样的大型对象,与pandas.DataFrame
等简单操作的成本相比,它可能很重要。类似地,生成x**2
可能需要一些时间,您可以通过使用线程(即从Process
而不是multiprocess.dummy
来更快地(对于轻量级对象)执行上述操作最初发布的解决方案或我的上面)。
如果您 需要共享multiprocess
(正如您的代码建议而不是问题所示),您可以通过创建共享内存{{1}来实现}。