2015-05-29 36 views
7

我有一个函数,它以图的节点id作为输入并计算图中的某些内容(不改变图形对象),然后将结果保存在文件系统中,我的代码如下所示:如何在Python中使用多处理时节省内存?

... 
# graph file is being loaded 
g = loadGraph(gfile='data/graph.txt') 
# list of nodeids is being loaded 
nodeids = loadSeeds(sfile='data/seeds.txt') 

import multiprocessing as mp 
# parallel part of the code 
print ("entering the parallel part ..") 
num_workers = mp.cpu_count() # 4 on my machine 
p = mp.Pool(num_workers) 
# _myParallelFunction(nodeid) {calculate something for nodeid in g and save it into a file} 
p.map(_myParallelFunction, nodeids) 
p.close() 
... 

问题是,当我将图加载到Python中时,它需要大量内存(大约2G,它实际上是一个包含数千个节点的大图),但是当它开始进入代码的并行部分(并行部分映射函数执行),似乎每个进程都有一个单独的g副本,我只是在我的机器上耗尽内存(它有6G RAM和3G交换),所以我想看看有没有办法让每个进程g的同一副本,只有内存才能保存它的一个副本?任何建议表示赞赏和感谢提前。

+0

我不太了解这个问题给你一个可靠的答案,然而一个建议是将图分成较小的部分,然后使用这些过程来基本上“分而治之”。 – KronoS

+1

您可以将图表放入一个自定义的'multiprocessing.Manager',它将允许所有进程使用'Manager'进程中托管的一个共享图形。但是,当访问共享图时,这会带来很大的性能损失,所以与顺序方法相比,它可能最终不会提高性能。 – dano

+1

你在Windows上运行这个吗?如果你在Linux上运行这个工具,理想情况下应该启动并防止创建多个'nodeIDs'副本。看到这个[评论](http://rhodesmill.org/brandon/2010/python-multiprocessing-linux-windows/#comment-160800553)和相关文章 – iruvar

回答

1

您的评论表明您一次处理一个节点:

# _myParallelFunction(nodeid) {calculate something for nodeid in g and save it into a file} 

我会创建一个从图形文件会在每次调用时返回单个节点的发电机的功能,以及发电机传递到p.map()函数而不是整个列表nodeids

+0

'multiprocessing.Pool.map'会将生成器变成一个列表在处理之前。你必须使用'multiprocessing.pool.imap'来避免这种情况。 – dano