gpt4 book ai didi

Python 多处理没有产生预期的加速

转载 作者:太空狗 更新时间:2023-10-30 01:38:05 27 4
gpt4 key购买 nike

我正在尝试使用 Python 的 multiprocessing.Pool 模块优化我的代码,但我没有获得逻辑上期望的加速结果。

我正在做的主要方法涉及计算大量向量和固定的大型稀疏矩阵的矩阵向量乘积。下面是一个玩具示例,它执行我需要的,但使用随机矩阵。

import time
import numpy as np
import scipy.sparse as sp

def calculate(vector, matrix = None):
for i in range(50):
v = matrix.dot(vector)
return v

if __name__ == '__main__':
N = 1e6
matrix = sp.rand(N, N, density = 1e-5, format = 'csr')
t = time.time()
res = []
for i in range(10):
res.append(calculate(np.random.rand(N), matrix = matrix))
print time.time() - t

该方法将在大约 30 秒后终止。

现在,由于 results 的每个元素的计算不依赖于任何其他计算的结果,很自然地认为并行计算将加速这个过程。这个想法是创建 4 个进程,如果每个进程都进行一些计算,那么完成所有进程所花费的时间应该减少 4 左右的某个因素。为此,我编写了以下代码:

import time
import numpy as np
import scipy.sparse as sp
from multiprocessing import Pool
from functools import partial

def calculate(vector, matrix = None):
for i in range(50):
v = matrix.dot(vector)
return v

if __name__ == '__main__':
N = 1e6
matrix = sp.rand(N, N, density = 1e-5, format = 'csr')

t = time.time()
input = []
for i in range(10):
input.append(np.random.rand(N))
mp = partial(calculate, matrix = matrix)
p = Pool(4)
res = p.map(mp, input)
print time.time() - t

我的问题是这段代码的运行时间略高于 20 秒,所以我什至没有将性能提高 2 倍!更糟糕的是,即使池包含 8 个进程,性能也 不会提高!知道为什么加速没有发生吗?


注意:我的实际方法需要更长的时间,并且输入向量存储在一个文件中。如果我将文件拆分为 4 部分,然后在每个文件的单独进程中手动运行我的脚本,则每个进程的终止速度是整个文件终止速度的四倍(如预期)。我很困惑为什么这种加速(这显然是可能的)没有发生在 multiprocessing.Pool


Edi:我刚刚找到了Multiprocessing.Pool makes Numpy matrix multiplication slower这个问题可能是相关的。不过,我必须检查一下。

最佳答案

尝试:

p = Pool(4)
for i in range(10):
input = np.random.rand(N)
p.apply_async(calculate, args=(input, matrix)) # perform function calculate as new process with arguments input and matrix

p.close()
p.join() # wait for all processes to complete

我怀疑“部分”对象和 map 导致了阻塞行为。 (虽然我没用过partial,所以不是很熟悉。)

“apply_async”(或“map_async”)是专门不阻塞的多处理方法 -(参见:Python multiprocessing.Pool: when to use apply, apply_async or map?)

通常,对于像这样的“令人尴尬的并行问题”,apply_async 适合我。

编辑:

我倾向于在完成后将结果写入 MySQL 数据库 - 如果这不是您的方法,我提供的实现将不起作用。如果您想使用列表中的顺序作为跟踪哪个条目的方式,“ map ”可能是正确的答案,但我仍然怀疑“部分”对象。

关于Python 多处理没有产生预期的加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26399345/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com