[英]How to speed up parallelization in Python
我有以下 function:
def function(arguments, process_number):
calclulations that build vector_1 and vector_2 of size 100000 each
return vector_1, vector_2
对于 200 个不同的 process_number 值,我需要并行运行这个 function。 我对按 process_number 排序的 output 不感兴趣,所以我使用 apply_async(),方式如下:
def parallelizing():
number_of_process
pool = mp.Pool(mp.cpu_count())
size = 100000
vector_1 = np.zeros(size)
vector_2 = np.zeros(size)
returned_object = [pool.apply_async(function,args=(args, procnum)) for procnum in range(number_of_process)]
pool.close()
pool.join()
for r in returned_object:
vector_1 += r.get()[0]
vector_2 += r.get()[1]
因此,归根结底,我只需将我从并行化的 function 中获得的所有向量相加即可。
问题是该进程使用的大部分时间实际上是存储 memory 来构建 [returned_object] 列表,我认为这真的没有必要,因为我只需要添加 function 的返回然后忘记。
因此,我试图避免构建一个庞大的对象列表,每个对象都包含至少两个大小为 100000 的浮动向量,并直接进入“添加”步骤。
有办法吗? 我应该定义一个全局变量并在 function 中写入它吗? 我担心它可能会导致并发和搞砸。 正如我所说,我真的不在乎得到一个有序的结果,因为我只需要添加一些东西。
从下面的 Cireo 答案编辑:
好的,只是为了确认我是否理解。 我不使用 apply_async 方法,而是执行以下操作:
def function(args, queue_1, queue_2):
#do calculation
queue.put(vector_1)
queue.put(vector_2)
在调用并行化的 function 内部,我只是简单地做
def parallelizing():
queue1 = Queue()
queue2=Queue()
processid = np.arange(200)
p = Process(target=f, args=(args,queue1,queue2,prcoessid))
p.start()
p.join()
我真正不明白的是,我如何不将事物放入队列中,这在我看来与创建列表一样计算密集,而是可以添加函数的返回值。 如果我做 Queue.put() 我最终不会得到与以前相同的列表吗?
听起来您已经将这个问题自我诊断为与
根本不要创建列表,只需使用 Queue 或类似方法将所有子流程的结果发送回主流程。 你说你不关心顺序,所以这应该很简单。
您还可以使用共享 memory 进行调查,或者只是跨进程共享 object(尽管第二个选项可能不够快)
https://docs.python.org/3/library/multiprocessing.shared_memory.html
我不太熟悉multiprocessing
模块,但我使用threading
,我不确定哪个会更好,但这就是我将如何线程:
import numpy as np
from threading import Thread
def function(arguments, process_number, results, index):
print(arguments, process_number)
#calclulations that build vector_1 and vector_2 of size 100000 each
# example arrays/vectors
vector_1 = np.zeros(10000)
vector_2 = np.zeros(10000)
results[index] = (vector_1, vector_2)
count = 200
threads = [None] * count
results = [None] * count
args = ("example", "arguments")
process_numbers = range(1, count + 1)
for process_number, i in zip(process_numbers, range(count)):
threads[i] = Thread(target=function, args=(args,process_number, results, i))
threads[i].start()
for i in range(count):
threads[i].join()
size = 10000
vector_1 = np.zeros(size)
vector_2 = np.zeros(size)
for result in results:
vector_1 += result[0]
vector_2 += result[1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.