繁体   English   中英

如何加快 Python 中的并行化

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM