我知道这是一个有点模糊和开放的问题,但我需要在这方面得到一些帮助,因为快速的Google/Stack Overflow搜索没有产生有用的信息。
其基本思想是使用多个进程来加快当前在循环中按顺序执行的昂贵计算。需要注意的是,我有两个重要的数据结构可以通过昂贵的函数访问:
- 一个数据结构将被所有进程读取,但不会被一个进程修改(因此可以复制到每个进程,假设内存大小不是问题,在这种情况下不是问题(
- 其他数据结构将花费大部分时间由进程读取,但偶尔会被写入,并且从那时起需要将此更新传播到所有进程
目前该程序基本上是这样工作的:
def do_all_the_things(self):
read_only_obj = {...}
read_write_obj = {...}
output = []
for i in range(4):
for j in range(4):
output.append(do_expensive_operation(read_only_obj, read_write_obj))
return output
在单处理器世界中,这很好,因为对read_write_obj
所做的任何更改都是按顺序访问的。
我想做的是在一个单独的进程中运行do_expensive_operation
的每个实例,以便可以充分利用多处理器。
我想了解的两件事是:
- 整个多处理过程是如何工作的。我看过队列和池,不明白在这种情况下应该使用哪一个
- 我觉得共享记忆(
read_only_obj
和read_write_obj
(会很复杂。这可能吗?明智的我该怎么做呢
感谢您抽出时间!
免责声明:我会帮助你,并为你提供一个工作示例,但我不是这个主题的专家。
第1点在某种程度上得到了回答
第2点在某种程度上已经得到了回答。
我过去在python中使用了不同的CPU绑定任务选项,这里有一个玩具示例供您学习:
from multiprocessing import Process, Queue
import time, random
def do_something(n_order, x, queue):
time.sleep(5)
queue.put((idx, x))
def main():
data = [1,2,3,4,5]
queue = Queue()
processes = [Process(target=do_something, args=(n,x,queue)) for n,x in enumerate(data)]
for p in processes:
p.start()
for p in processes:
p.join()
unsorted_result = [queue.get() for _ in processes]
result = [i[1] for i in sorted(unsorted_result)]
print(result)
您可以在循环中编写相同的内容,而不是使用队列,并检查所消耗的时间(在这种愚蠢的情况下,出于测试目的,是睡眠(,您会意识到,正如预期的那样,您将时间缩短了大约运行的进程数。事实上,这是我的计算机中为您提供的确切脚本的结果(第一个多进程和第二个循环(:
[1, 2, 3, 4, 5]
real 0m5.240s
user 0m0.397s
sys 0m0.260s
[1, 4, 9, 16, 25]
real 0m25.104s
user 0m0.051s
sys 0m0.030s
关于read_only
或read and write
对象,我需要更多信息来提供帮助。这些是什么类型的物体?它们有索引吗?