如何并行查找列表的最大值?
How to find the maximum value of a list in parallel?
我正在使用一个函数,该函数采用值的组合并更新计算值。如果我将几个组合传递给该函数,它将计算几个不同的值,我想保留所有这些值中的最大值。为了加快这个过程,我 运行 将它 并行 。
简化,我有一个函数,它获取当前最大值并更新它(如果需要),给定一个列表。我如何运行这个函数并行加速计算,与所有活动进程共享值,以便当前值始终是最大值?最后,我想从组合列表中知道 combination/list 会给我最大值。
在这个使用多处理模块的例子中,脚本应该 return 62(最大值)而不是有时 returns 45。这里发生了什么,我需要改变什么?
from multiprocessing import Value, Process
import time
def update_best(numbers, best):
for n in numbers:
time.sleep(.1) # working ...
if n > best.value:
best.value = n
nos = [[1.1,2.1,3.1], [62,5.2,4.2], [7.3,8.3,9.3], [3.4,4.4,5.4], [45,4.5,3.5]]
for combo in nos:
best = Value('f', .42)
p1 = Process(target=update_best, args=(combo,best,))
p2 = Process(target=update_best, args=(combo,best,))
p1.start()
p2.start()
print("end")
time.sleep(3)
print(f"best = {best.value}")
编辑:非平行版本如下所示:
def update_best(numbers):
global best
for n in numbers:
time.sleep(.1)
if n > best:
best = n
nos = [[1.1,2.1,3.1], [62,5.2,4.2], [7.3,8.3,9.3], [3.4,4.4,5.4], [45,4.5,3.5]]
best = .42
for combo in nos:
update_best(combo)
print("end")
time.sleep(3)
print(f"best = {best}")
其实并不复杂。我建议使用 multiprocessing.Pool
及其函数 map
。像这样:
import os
import multiprocessing as mp
def partition(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
def mymax(vals):
print(os.getpid(), vals)
return max(vals)
def pmax(vals):
with mp.Pool(5) as pool:
results = pool.map(mymax, partition(vals, 5))
return max(results)
if __name__ == "__main__":
m = pmax([1.1,2.1,3.1, 62,5.2,4.2, 7.3,8.3,9.3, 3.4,4.4,5.4, 45,4.5,3.5])
print(m)
输出:
$ python3 pmax.py
829763 [1.1, 2.1, 3.1, 62, 5.2]
829764 [4.2, 7.3, 8.3, 9.3, 3.4]
829765 [4.4, 5.4, 45, 4.5, 3.5]
62
重要提示: 您必须在主文件中使用 if __name__ == "__main__":
。否则它不会工作。
解释:
除非使用某些 IPC 原语(共享内存、消息队列等),否则不能与不同进程共享变量。
但是,您可以对问题应用分而治之法,分两个阶段解决:
- 并行处理事情。主进程必须等待所有并行处理完毕才能继续。
- 在这种情况下,您找到 sub-array
的最大值
- 合并这些结果以产生最终输出(这是在主进程中完成的)
- 在这种情况下:找到那些中间最大值的最大质数(双关语)。
我正在使用一个函数,该函数采用值的组合并更新计算值。如果我将几个组合传递给该函数,它将计算几个不同的值,我想保留所有这些值中的最大值。为了加快这个过程,我 运行 将它 并行 。
简化,我有一个函数,它获取当前最大值并更新它(如果需要),给定一个列表。我如何运行这个函数并行加速计算,与所有活动进程共享值,以便当前值始终是最大值?最后,我想从组合列表中知道 combination/list 会给我最大值。
在这个使用多处理模块的例子中,脚本应该 return 62(最大值)而不是有时 returns 45。这里发生了什么,我需要改变什么?
from multiprocessing import Value, Process
import time
def update_best(numbers, best):
for n in numbers:
time.sleep(.1) # working ...
if n > best.value:
best.value = n
nos = [[1.1,2.1,3.1], [62,5.2,4.2], [7.3,8.3,9.3], [3.4,4.4,5.4], [45,4.5,3.5]]
for combo in nos:
best = Value('f', .42)
p1 = Process(target=update_best, args=(combo,best,))
p2 = Process(target=update_best, args=(combo,best,))
p1.start()
p2.start()
print("end")
time.sleep(3)
print(f"best = {best.value}")
编辑:非平行版本如下所示:
def update_best(numbers):
global best
for n in numbers:
time.sleep(.1)
if n > best:
best = n
nos = [[1.1,2.1,3.1], [62,5.2,4.2], [7.3,8.3,9.3], [3.4,4.4,5.4], [45,4.5,3.5]]
best = .42
for combo in nos:
update_best(combo)
print("end")
time.sleep(3)
print(f"best = {best}")
其实并不复杂。我建议使用 multiprocessing.Pool
及其函数 map
。像这样:
import os
import multiprocessing as mp
def partition(l, n):
for i in range(0, len(l), n):
yield l[i:i + n]
def mymax(vals):
print(os.getpid(), vals)
return max(vals)
def pmax(vals):
with mp.Pool(5) as pool:
results = pool.map(mymax, partition(vals, 5))
return max(results)
if __name__ == "__main__":
m = pmax([1.1,2.1,3.1, 62,5.2,4.2, 7.3,8.3,9.3, 3.4,4.4,5.4, 45,4.5,3.5])
print(m)
输出:
$ python3 pmax.py
829763 [1.1, 2.1, 3.1, 62, 5.2]
829764 [4.2, 7.3, 8.3, 9.3, 3.4]
829765 [4.4, 5.4, 45, 4.5, 3.5]
62
重要提示: 您必须在主文件中使用 if __name__ == "__main__":
。否则它不会工作。
解释:
除非使用某些 IPC 原语(共享内存、消息队列等),否则不能与不同进程共享变量。
但是,您可以对问题应用分而治之法,分两个阶段解决:
- 并行处理事情。主进程必须等待所有并行处理完毕才能继续。
- 在这种情况下,您找到 sub-array 的最大值
- 合并这些结果以产生最终输出(这是在主进程中完成的)
- 在这种情况下:找到那些中间最大值的最大质数(双关语)。