Python for 循环多处理
Python for loop multiprocessing
我有一个矩阵矩阵,我需要对其进行计算(即 x x y x z x z 矩阵,我需要对每个 z x z 矩阵执行计算,所以 x*y 总操作).目前,我正在遍历矩阵的前两个维度并执行计算,但它们是完全独立的。有没有一种方法可以并行计算这些矩阵,而无需事先知道会有多少这样的矩阵(即 x 和 y 未知)。
是;请参阅 multiprocessing 模块。这是一个示例(根据文档中的示例进行了调整以适合您的用例)。 (为了简单起见,我在这里假设 z = 1
,因此 f
采用标量。)
from multiprocessing import Pool
# x = 2, y = 3, z = 1 - needn't be known in advance
matrix = [[1, 2, 3], [4, 5, 6]]
def f(x):
# Your computation for each z-by-z submatrix goes here.
return x**2
with Pool() as p:
flat_results = p.map(f, [x for row in matrix for x in row])
# If you don't need to preserve the x*y shape of the input matrix,
# you can use `flat_results` and skip the rest.
x = len(matrix)
y = len(matrix[0])
results = [flat_results[i*y:(i+1)*y] for i in range(x)]
# Now `results` contains `[[1, 4, 9], [16, 25, 36]]`
这会将 x * y
计算分配给多个进程(每个 CPU 核心一个;这可以通过向 Pool()
提供参数来调整)。
根据您正在做的事情,考虑首先使用 numpy 尝试矢量化操作(而不是 for 循环);您可能会发现它的速度足以使多处理变得不必要。 (如果在此示例中 matrix
是一个 numpy 数组,则代码将只是 results = matrix**2
。)
我在 python 中处理并行处理的方法是定义一个函数来执行我想要的操作,然后使用 multiprocessing.Pool.starmap
并行应用它。在不知道您在计算什么以及如何计算的情况下,很难为您的问题建议任何代码。
import multiprocessing as mp
def my_function(matrices_to_compare, matrix_of_matrices):
m1 = matrices_to_compare[0]
m2 = matrices_to_compare[1]
result = m1 - m2 # or whatever you want to do
return result
matrices_x = <list of x matrices>
matrices_y = <list of y matrices>
matrices_to_compare = list(zip(matrices_x,matrices_y))
with mp.Pool(mp.cpu_count()) as pool:
results = pool.starmap(my_function,
[(x, matrix_of_matrices) for x in matrices_to_compare],
chunksize=1)
其他答案提出的多处理池方法的替代方法 - 如果您有可用的 GPU,最直接的方法可能是使用张量代数包来利用它,例如 cupy
或 torch
.
您还可以通过使用 cython 或 numba jit 编译您的代码(cpu)来获得更多加速(然后对于 gpu 编程还有 numba.cuda
,但是需要一些背景才能使用).
我有一个矩阵矩阵,我需要对其进行计算(即 x x y x z x z 矩阵,我需要对每个 z x z 矩阵执行计算,所以 x*y 总操作).目前,我正在遍历矩阵的前两个维度并执行计算,但它们是完全独立的。有没有一种方法可以并行计算这些矩阵,而无需事先知道会有多少这样的矩阵(即 x 和 y 未知)。
是;请参阅 multiprocessing 模块。这是一个示例(根据文档中的示例进行了调整以适合您的用例)。 (为了简单起见,我在这里假设 z = 1
,因此 f
采用标量。)
from multiprocessing import Pool
# x = 2, y = 3, z = 1 - needn't be known in advance
matrix = [[1, 2, 3], [4, 5, 6]]
def f(x):
# Your computation for each z-by-z submatrix goes here.
return x**2
with Pool() as p:
flat_results = p.map(f, [x for row in matrix for x in row])
# If you don't need to preserve the x*y shape of the input matrix,
# you can use `flat_results` and skip the rest.
x = len(matrix)
y = len(matrix[0])
results = [flat_results[i*y:(i+1)*y] for i in range(x)]
# Now `results` contains `[[1, 4, 9], [16, 25, 36]]`
这会将 x * y
计算分配给多个进程(每个 CPU 核心一个;这可以通过向 Pool()
提供参数来调整)。
根据您正在做的事情,考虑首先使用 numpy 尝试矢量化操作(而不是 for 循环);您可能会发现它的速度足以使多处理变得不必要。 (如果在此示例中 matrix
是一个 numpy 数组,则代码将只是 results = matrix**2
。)
我在 python 中处理并行处理的方法是定义一个函数来执行我想要的操作,然后使用 multiprocessing.Pool.starmap
并行应用它。在不知道您在计算什么以及如何计算的情况下,很难为您的问题建议任何代码。
import multiprocessing as mp
def my_function(matrices_to_compare, matrix_of_matrices):
m1 = matrices_to_compare[0]
m2 = matrices_to_compare[1]
result = m1 - m2 # or whatever you want to do
return result
matrices_x = <list of x matrices>
matrices_y = <list of y matrices>
matrices_to_compare = list(zip(matrices_x,matrices_y))
with mp.Pool(mp.cpu_count()) as pool:
results = pool.starmap(my_function,
[(x, matrix_of_matrices) for x in matrices_to_compare],
chunksize=1)
其他答案提出的多处理池方法的替代方法 - 如果您有可用的 GPU,最直接的方法可能是使用张量代数包来利用它,例如 cupy
或 torch
.
您还可以通过使用 cython 或 numba jit 编译您的代码(cpu)来获得更多加速(然后对于 gpu 编程还有 numba.cuda
,但是需要一些背景才能使用).