[英]How to use multiprocessing for accelerate the following function?
我有以下for循環:
for j in range(len(a_nested_list_of_ints)):
arr_1_, arr_2_, arr_3_ = foo(a_nested_list_of_ints[j])
arr_1[j,:] = arr_1_.data.numpy()
arr_2[j,:] = arr_2_.data.numpy()
arr_3[j,:] = arr_3_.data.numpy()
其中a_nested_list_of_ints
是一個嵌套的int列表。 但是要花很多時間才能完成。 如何通過多處理優化它? 到目前為止,我嘗試使用multiprocessing
p = Pool(5)
for j in range(len(a_nested_list_of_ints)):
arr_1_, arr_2_, arr_3_ = p.map(foo,a_nested_list_of_ints[j])
arr_1[j,:] = arr_1_.data.numpy()
arr_2[j,:] = arr_2_.data.numpy()
arr_3[j,:] = arr_3_.data.numpy()
但是,我得到了:
ValueError: not enough values to unpack (expected 3, got 2)
這里:
arr_1_, arr_2_, arr_3_ = p.map(foo,a_nested_list_of_ints[j])
如何更快地完成上述操作? 我甚至嘗試過使用starmap,但它不起作用。
這是一個有效的pool
演示:
In [11]: def foo(i):
...: return np.arange(i), np.arange(10-i)
...:
In [12]: with multiprocessing.Pool(processes=2) as pool:
...: x = pool.map(foo, range(10))
...:
In [13]: x
Out[13]:
[(array([], dtype=int64), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])),
(array([0]), array([0, 1, 2, 3, 4, 5, 6, 7, 8])),
(array([0, 1]), array([0, 1, 2, 3, 4, 5, 6, 7])),
(array([0, 1, 2]), array([0, 1, 2, 3, 4, 5, 6])),
(array([0, 1, 2, 3]), array([0, 1, 2, 3, 4, 5])),
(array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4])),
(array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3])),
(array([0, 1, 2, 3, 4, 5, 6]), array([0, 1, 2])),
(array([0, 1, 2, 3, 4, 5, 6, 7]), array([0, 1])),
(array([0, 1, 2, 3, 4, 5, 6, 7, 8]), array([0]))]
pool.map
正在進行迭代,而不是一些外部for
循環。
並且更接近你的例子:
In [14]: def foo(alist):
...: return np.arange(*alist), np.zeros(alist,int)
...:
...:
In [15]: alists=[(0,3),(1,4),(1,6,2)]
In [16]: with multiprocessing.Pool(processes=2) as pool:
...: x = pool.map(foo, alists)
...:
In [17]: x
Out[17]:
[(array([0, 1, 2]), array([], shape=(0, 3), dtype=int64)),
(array([1, 2, 3]), array([[0, 0, 0, 0]])),
(array([1, 3, 5]), array([[[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]]]))]
請注意, pool.map
返回一個列表,其中包含從alists
生成的所有案例。 解壓縮x
是沒有意義的。
x,y = pool.map(...) # too many values to pack error
我可以使用zip*
成語解壓縮x
:
In [21]: list(zip(*x))
Out[21]:
[(array([0, 1, 2]), array([1, 2, 3]), array([1, 3, 5])),
(array([], shape=(0, 3), dtype=int64), array([[0, 0, 0, 0]]), array([[[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]]]))]
這是一個2元組的列表; 實際上是轉置的列表版本。 這可以解壓縮:
In [23]: y,z = zip(*x)
In [24]: y
Out[24]: (array([0, 1, 2]), array([1, 2, 3]), array([1, 3, 5]))
In [25]: z
Out[25]:
(array([], shape=(0, 3), dtype=int64), array([[0, 0, 0, 0]]), array([[[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]]]))
這是我經常使用的多處理實現。 它會將您的列表(在本例中為a_nested_list_of_ints
)拆分為您擁有的多個核心。 然后它在每個拆分列表上運行你的foo
函數,每個核心一個列表。
def split_list(all_params, instances):
return list(np.array_split(all_params, instances))
# split the list up into equal chucks for each core
n_proc = multiprocessing.cpu_count()
split_items = split_list(to_calc, n_proc)
# create the multiprocessing pool
pool = Pool(processes=n_proc)
all_calcs = []
for i in range(n_proc):
# the arguments to the foo definition have to be a tuple - (split[i],)
async_calc = pool.apply_async(foo, (split_items[i],))
all_calcs.append(async_calc)
pool.close()
pool.join()
# get results
all_results = []
for result in all_calcs:
all_results += result.get()
print(all_results)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.