对于我的并行化大计算工作的4个进程中的每一个,我想测试一些数字是否是4GB集合S
的成员。
使用这种方法时,问题是t = Process(target=somefunc,args=(S,))
将4GB数据传递给每个进程,这对我的计算机来说太大了(4 * 4 = 16 GB)!
如何在这个多处理作业中使用S
作为全局变量,而不是必须将S
传递(并复制)到每个进程?
from multiprocessing import Process
from random import randint
def somefunc(S):
a = randint(0, 100) # simplified example
print a in S
return
def main():
S = set([1, 2, 7, 19, 13]) # here it's a 4 GB set in my real program
for i in range(4):
t = Process(target=somefunc,args=(S,))
t.start()
t.join()
if __name__ == '__main__':
main()
注意:我已经考虑过使用数据库+客户端/服务器(甚至只是SQlite),但我真的想要使用set / dict查找的速度,这比数据库调用更快(按数量级)。
那么使用joblib.Parallel
呢?
S = set(range(50000000) # ~ 3.5 Gb
def somefunc():
a = randint(0, 100) # simplified example
print a in S
return
def main():
out = Parallel(n_jobs=4, verbose=1)(
delayed(somefunc)() for i in range(50))
if __name__ == '__main__':
main()
我可能不在这里,但这不会重复。在测试中,Python3.6用于此脚本的内存永远不会破坏4 Gb。
或者你可以使用S作为全局变量而不将其传递给somefunc
:
from multiprocessing import Process
from random import randint
def somefunc():
a = randint(0, 100)
print(a in S)
return
def main(): # here it's a 4 GB set in my real program
for i in range(4):
t = Process(target=somefunc)
t.start()
t.join()
if __name__ == '__main__':
S = set(range(50000000))
main()
据我所知,从测试这两种方法产生正确的输出,并没有重复S
。