两个for循环的多重处理
Multiprocessing of two for loops
我正在努力实现 python (2.7) 中的算法以并行化物理问题的计算。在两个变量(假设 a 和 b)上有一个参数 space 我想 运行 我写的程序 f(a,b) 其中 returns 另外两个变量 c 和 d .
到目前为止,我在 a 和 b 上使用了两个 for
循环来计算 c 和 d 的两个数组,然后将它们保存为 txt 文档。由于参数space比较大,每次计算其中的一个点f(a,b)的时间比较长,所以把我的8个CPU核全部用于参数[=就好了20=]扫描。
我已经阅读了有关多线程和多处理的信息,多处理似乎正是我正在寻找的内容。您是否知道此应用程序的良好代码示例或资源以了解我相当简单的应用程序的多处理基础知识?
这是一个示例,说明如何将多处理与一个简单的函数一起使用,该函数接受两个参数和 returns 两个数字的元组,以及一个参数 space,您要对其执行计算:
from itertools import product
from multiprocessing import Pool
import numpy as np
def f(a, b):
c = a + b
d = a * b
return (c, d)
a_vals = [1, 2, 3, 4, 5, 6]
b_vals = [10, 11, 12, 13, 14, 15, 16, 17]
na = len(a_vals)
nb = len(b_vals)
p = Pool(8) # <== maximum number of simultaneous worker processes
answers = np.array(p.starmap(f, product(a_vals, b_vals))).reshape(na, nb, 2)
c_vals = answers[:,:,0]
d_vals = answers[:,:,1]
这给出了以下内容:
>>> c_vals
array([[11, 12, 13, 14, 15, 16, 17, 18],
[12, 13, 14, 15, 16, 17, 18, 19],
[13, 14, 15, 16, 17, 18, 19, 20],
[14, 15, 16, 17, 18, 19, 20, 21],
[15, 16, 17, 18, 19, 20, 21, 22],
[16, 17, 18, 19, 20, 21, 22, 23]])
>>> d_vals
array([[ 10, 11, 12, 13, 14, 15, 16, 17],
[ 20, 22, 24, 26, 28, 30, 32, 34],
[ 30, 33, 36, 39, 42, 45, 48, 51],
[ 40, 44, 48, 52, 56, 60, 64, 68],
[ 50, 55, 60, 65, 70, 75, 80, 85],
[ 60, 66, 72, 78, 84, 90, 96, 102]])
p.starmap
returns 一个二元组列表,然后从中提取 c 和 d 值。
这假定您将在返回所有结果后在主程序中执行您的文件 I/O。
附录:
如果 p.starmap
不可用 (Python 2),那么您可以更改函数以获取单个输入(2 元素元组):
def f(inputs):
a, b = inputs
# ... etc as before ...
然后在上面的代码中使用p.map
代替p.starmap
。
如果不方便改函数(比如也从别处调用),那当然可以写个wrapper函数:
def f_wrap(inputs):
a, b = inputs
return f(a, b)
并改为调用它。
我正在努力实现 python (2.7) 中的算法以并行化物理问题的计算。在两个变量(假设 a 和 b)上有一个参数 space 我想 运行 我写的程序 f(a,b) 其中 returns 另外两个变量 c 和 d .
到目前为止,我在 a 和 b 上使用了两个 for
循环来计算 c 和 d 的两个数组,然后将它们保存为 txt 文档。由于参数space比较大,每次计算其中的一个点f(a,b)的时间比较长,所以把我的8个CPU核全部用于参数[=就好了20=]扫描。
我已经阅读了有关多线程和多处理的信息,多处理似乎正是我正在寻找的内容。您是否知道此应用程序的良好代码示例或资源以了解我相当简单的应用程序的多处理基础知识?
这是一个示例,说明如何将多处理与一个简单的函数一起使用,该函数接受两个参数和 returns 两个数字的元组,以及一个参数 space,您要对其执行计算:
from itertools import product
from multiprocessing import Pool
import numpy as np
def f(a, b):
c = a + b
d = a * b
return (c, d)
a_vals = [1, 2, 3, 4, 5, 6]
b_vals = [10, 11, 12, 13, 14, 15, 16, 17]
na = len(a_vals)
nb = len(b_vals)
p = Pool(8) # <== maximum number of simultaneous worker processes
answers = np.array(p.starmap(f, product(a_vals, b_vals))).reshape(na, nb, 2)
c_vals = answers[:,:,0]
d_vals = answers[:,:,1]
这给出了以下内容:
>>> c_vals
array([[11, 12, 13, 14, 15, 16, 17, 18],
[12, 13, 14, 15, 16, 17, 18, 19],
[13, 14, 15, 16, 17, 18, 19, 20],
[14, 15, 16, 17, 18, 19, 20, 21],
[15, 16, 17, 18, 19, 20, 21, 22],
[16, 17, 18, 19, 20, 21, 22, 23]])
>>> d_vals
array([[ 10, 11, 12, 13, 14, 15, 16, 17],
[ 20, 22, 24, 26, 28, 30, 32, 34],
[ 30, 33, 36, 39, 42, 45, 48, 51],
[ 40, 44, 48, 52, 56, 60, 64, 68],
[ 50, 55, 60, 65, 70, 75, 80, 85],
[ 60, 66, 72, 78, 84, 90, 96, 102]])
p.starmap
returns 一个二元组列表,然后从中提取 c 和 d 值。
这假定您将在返回所有结果后在主程序中执行您的文件 I/O。
附录:
如果 p.starmap
不可用 (Python 2),那么您可以更改函数以获取单个输入(2 元素元组):
def f(inputs):
a, b = inputs
# ... etc as before ...
然后在上面的代码中使用p.map
代替p.starmap
。
如果不方便改函数(比如也从别处调用),那当然可以写个wrapper函数:
def f_wrap(inputs):
a, b = inputs
return f(a, b)
并改为调用它。