【发布时间】:2018-03-07 06:01:52
【问题描述】:
在 for 循环中,我调用一个函数两次,但使用不同的参数集(argSet1、argSet2)在 for 循环的每次迭代中都会发生变化。我想并行化这个操作,因为一组参数导致被调用函数运行得更快,而另一组参数导致函数运行缓慢。请注意,我不想为此操作使用两个 for 循环。我还有另一个要求:这些函数中的每一个都将执行一些并行操作,因此我不希望 argSet1 或 argSet2 的任何函数运行不止一次,因为我计算的资源有限有。确保具有两个参数集的函数都在运行将帮助我尽可能多地利用 CPU 内核。以下是在没有并行化的情况下正常执行的方法:
def myFunc(arg1, arg2):
if arg1:
print ('do something that does not take too long')
else:
print ('do something that takes long')
for i in range(10):
argSet1 = arg1Storage[i]
argSet1 = arg2Storage[i]
myFunc(argSet1)
myFunc(argSet2)
这绝对不会利用我拥有的计算资源。这是我尝试并行化操作:
from multiprocessing import Process
def myFunc(arg1, arg2):
if arg1:
print ('do something that does not take too long')
else:
print ('do something that takes long')
for i in range(10):
argSet1 = arg1Storage[i]
argSet1 = arg2Storage[i]
p1 = Process(target=myFunc, args=argSet1)
p1.start()
p2 = Process(target=myFunc, args=argSet2)
p2.start()
但是,这样每个函数及其各自的参数将被调用 10 次,并且事情变得非常缓慢。鉴于我对多处理的了解有限,我试图通过在 for 循环的末尾添加 p1.join() 和 p2.join() 来进一步改进,但这仍然会导致速度变慢,因为 p1 完成得更快,事情要等到 @ 987654330@ 已完成。我还考虑过使用multiprocessing.Value 与函数进行一些通信,但是我必须在函数内为每个函数调用添加一个while 循环,这会再次减慢一切。我想知道是否有人可以提供一个实用的解决方案?
【问题讨论】:
-
如果你只想调用一次,为什么要在每个 argSet 的 for 循环中调用 myFunc 10 次?
-
@dnswlt 对不起,我忘了提到每次迭代的参数都会改变。现在更新我的问题
-
你应该使用一个进程池(不管你想要多少),并在开始时提交所有作业,并让它们全部运行到完成。这样您就可以在整个运行过程中利用所有可用的内核,而目前两个并行作业中较快的一个将首先完成,然后该内核上不会发生任何事情。
-
@JohnZwinck 谢谢,但请您尝试发布答案吗?我对多处理还很陌生,不清楚如何正确使用它。
-
我认为您对需求的定义不够明确。 1.您不想并行化所有运行 2.您不想一次仅并行化 2 个调用(您的最后一次尝试)。所以你想要什么?一次并行化所有 10 个快速调用,然后依次运行慢速调用?在顺序运行的同时运行慢速调用并行运行快速运行?这种情况下,当慢跑结束时,要不要进入下一个慢跑,仍然并行快速运行?
标签: python python-3.x ubuntu for-loop multiprocessing