如何在 python 中跨多处理器共享内存?
Posted
技术标签:
【中文标题】如何在 python 中跨多处理器共享内存?【英文标题】:How to share memory across multiprocessors in python? 【发布时间】:2021-12-27 08:02:41 【问题描述】:我有一个很大的字典,我想通过多重处理来处理它,如下所示:
import multiprocessing as mp
with mp.Pool() as p:
# x is a dictionary of dictionary, f is a function, v is a dictionary
y = dict(p.map(f, ((k, v, *something*) for k, v in x.items())))
但是,上面的内容甚至比单次处理还要慢。我怀疑将我的大字典复制到每个子处理器会使其变慢。我尝试 manager 但我没有找到正确的语法。我想问一下在python中跨多处理器共享内存的正确方法。
由于我将多次重用子处理器,因此在每个子处理器中预加载字典也很好。但同样,我没有找到正确的语法。
【问题讨论】:
在您的情况下,操作系统非常重要。有些系统支持 fork 并有效地处理数据,甚至可以有一个写时复制的 fork,其中数据仅在修改时才被复制,原因是 Windows 不支持这两者,所有东西都必须进行昂贵的序列化. 尝试使用函数imap
而不是map
并指定一个chunksize 参数(一个好的值应该是x
上的键数除以(4 * 池大小)。因此,如果您在 x
中有 8 个内核和 100_000 个条目,您将使用 100_000 // 32 的 chunksize 值。这至少应该有一些帮助。
感谢您的意见。速度慢的问题是将整个数据(~5GB)复制到每个子处理器。我相信解决它的一种方法是将 CPU 的单独逻辑核心视为不同的服务器。每个服务器预加载不同部分的数据并接收来自主服务器的请求。但是,python 支持吗?
【参考方案1】:
我终于成功地使用 mp.Process 预加载了我的数据集。
代码如下:
import multiprocessing as mp
class mySubprocess(mp.Process):
def __init__(self, path, in_queue, out_queue, *args, **kwargs):
super().__init__(*args, **kwargs)
self.my_dict = ** preload something **
self.in_queue = in_queue
self.out_queue = out_queue
def run(self):
while True:
my_input= self.in_queue.get()
my_return = ** do something **
self.out_queue.put(my_return)
class myClass:
def __init__(self, path_list, *args, **kwargs):
n = len(path_list)
self.in_queue = [mp.Queue()] * n
self.out_queue = [mp.Queue()] * n
self.processes = [mySubprocess(path, self.in_queue[i], self.out_queue[i]) for (i, path) in enumerate(path_list)]
for p in self.processes:
p.start()
def run(self, ** something **):
for q in self.in_queue:
my_input = ** do something **
q.put(my_input)
output_list = []
for q in self.out_queue:
my_return = q.get()
output_list.append(my_return)
【讨论】:
以上是关于如何在 python 中跨多处理器共享内存?的主要内容,如果未能解决你的问题,请参考以下文章