在每个进程中测试一个数字是否为4GB集的成员,而不重复集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在每个进程中测试一个数字是否为4GB集的成员,而不重复集相关的知识,希望对你有一定的参考价值。

对于我的并行化大计算工作的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

以上是关于在每个进程中测试一个数字是否为4GB集的成员,而不重复集的主要内容,如果未能解决你的问题,请参考以下文章

Linux进程内存如何管理?

从Int获取单个数字而不使用字符串?

我应该为每个功能编写多少个集成测试(或场景)?

可变参数模板类:是不是可以为每个可变参数模板参数实现一个唯一的成员函数?

当 Windows 可以访问的总内存也限制为 4GB 时,Windows 如何将 4GB 地址空间分配给多个进程

编程上下文中的虚拟地址空间