【发布时间】:2021-04-15 08:01:41
【问题描述】:
在我的程序中,我需要生成 16 个多处理池,以在我的 3950x 上使用 16 个内核。我有一个初始化器,它在 spawn 子进程中初始化三个全局变量(总共大约 300kb)。
在使用初始化程序之前,每个进程大约需要 1 秒才能生成。现在 16 个过程总共需要大约 100 秒!知道为什么现在这么慢吗?示例代码如下:
def set_mp_global_vars(bc, bm, bf_n):
"""mp initialiser which sets global vars to reduce mp overhead"""
global base_comps, base_matches, bf_names
base_comps = bc
base_matches = bm
bf_names = bf_n
int_pool_workers = mp.cpu_count()
pool = mp.Pool(processes=int_pool_workers, initializer=set_mp_global_vars,
initargs=(base_comps, base_matches, bf_names))
【问题讨论】:
-
在进程之间传递数据涉及一方面进行酸洗,另一方面取消酸洗,以及一些磁盘 I/O,这可能是很多开销——尽管 100 倍确实看起来太多了……
-
但这是我试图避免的,但设置全局变量,这样我就不需要在每次需要这些变量时腌制并将其传递给进程。假设我有 20,000 个进程,那么我只需为每个池初始化 16 次,而不是腌制 20,000 次。
-
更新:看来是变量“bm”导致了缓慢。删除“bm”作为参数并将 base_matches 作为全局变量会导致 16 个进程在大约 16 秒内生成。 “bm”是约 8000 个自定义类实例的嵌套默认字典。 getsizeof 说它只有大约 300kb,但不确定这是否只是参考对象而不是真实大小。
-
已经有一段时间了,但我记得读过
getsizeof()的值不可靠。 -
getsizeof()返回那个对象的大小。如果该对象是一个包含对其他对象的引用的容器,它只会递归地计算保存这些顶级引用的内存,而不是它们引用的对象的大小。例如L = [os.urandom(1<<30)]创建一个包含对 1GB 缓冲区的引用的列表,但sys.getsizeof(L) == 64。
标签: python windows multiprocessing python-3.8