如何使计算循环易于拆分和恢复?



我想为给定的计算问题找到 0..99 中i, j, k的最佳参数,我需要运行:

for i in range(100):
for j in range(100):
for k in range(100):
dothejob(i, j, k)    # 1 second per computation

这总共需要 10^6 秒,即 11.5 天。

我开始将工作分为 4 个进程(以使用 100 核 CPU 计算机的 4% 计算能力):

for i in range(100):
if i % 4 != 0:      #  replace != 0 by 1, 2, or 3 for the parallel scripts #2, #3, #4
continue
for j in range(100):
for k in range(100):
dothejob(i, j, k)
with open('done.log', 'a+') as f:    # log what has been done
f.write("%i %in" % (i, j))

但是我对这种方法有问题:

我必须运行python script.py,然后打开script.py,将第 2 行替换为if i % 4 != 1,然后运行python script.py,然后打开script.py,将第 2 行替换为if i % 4 != 2,然后运行python script.py,然后
  1. 打开script.py,将第 2 行替换为if i % 4 != 3,然后运行python script.py

  2. 假设循环中断(需要重新启动计算机,或崩溃或其他任何事情等)。至少我们知道done.log中已经完成的所有 (i, j)(所以我们不需要再次从 0 开始),但没有简单的方法可以恢复工作。(好的,我们可以打开done.log,解析它,丢弃重新启动循环时已经完成的(i,j),我开始这样做 - 但我有一种感觉,以一种肮脏的方式,已经存在的东西)

我正在寻找一个更好的解决方案(但例如map/reduce对于这个小任务来说可能是一个矫枉过正,并且在Python中的几行中不容易使用)。

问题:如何使计算for i in range(100): for j in range(100): for k in range(100): dothejob(i, j, k)多个进程之间轻松拆分,并且在 Python 中易于恢复(例如重新启动后)?

只需使用流程池映射产品,例如:

import itertools as it
from multiprocessing import Pool
the_args = it.product(range(100), range(100), range(100))
pool = Pool(4)
def jobWrapper(args): #we need this to unpack the (i, j, k) tuple 
return dothejob(*args)
res = pool.map(jobWrapper, the_args)

如果您想恢复它,从日志中知道 las(i, j, k),只需跳过之前从the_args计算的所有内容:

the_args = it.product(range(100), range(100), range(100))
#skip previously computed 
while True:
if next(the_args) == (i, j, k):
break
...

使用 las 计算值(i, j, k)元组。

相关内容

  • 没有找到相关文章

最新更新