Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使计算循环易于拆分和恢复?_Python_Loops_Multiprocessing_Computation - Fatal编程技术网

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

Python 如何使计算循环易于拆分和恢复?,python,loops,multiprocessing,computation,Python,Loops,Multiprocessing,Computation,对于给定的计算问题,我想在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个进程(使用我的4核CPU计算机的100%计算能力): 但我对这种方法有问题: 我必须运行pyth

对于给定的计算问题,我想在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个进程(使用我的4核CPU计算机的100%计算能力):

但我对这种方法有问题:

  • 我必须运行
    python script.py
    ,然后打开
    script.py
    ,如果我%4!=1,然后运行
    python script.py
    ,然后打开
    script.py
    ,如果i%4!=2,然后运行
    python script.py
    ,然后打开
    script.py
    ,如果i%4!=3,然后运行
    python script.py

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

  • 我正在寻找一个更好的解决方案(例如,对于这个小任务来说,可能是一个过度的解决方案,并且在Python的几行代码中不容易使用)


    问题:如何对范围(100)中的i进行计算
    :范围(100)中的j:范围(100)中的k: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 = it.product(range(100), range(100), range(100))
    #skip previously computed 
    while True:
        if next(the_args) == (i, j, k):
            break
    ...
    

    作为
    (i,j,k)
    具有las计算值的元组。

    不阅读所有问题:是否有结果可以在某个点缓存和重用?@rockstaid:没有。每个具有新i,j,k的计算都是一个全新的任务,不能重用过去工作中的任何内容。你不能像这里这样使用并行for循环吗@Basj对于自动拆分和任务管理,请查看上面提到的库。然而,这仍然假设存在一个“管理者”流程,在工人身上生成任务。如果你的管理器死机,或者电脑重新启动,你必须考虑从磁盘加载最后一个已知的状态(这正是解析所要做的…)。如果你需要某种持久性,可以在重新启动后生存下来,那么我首先要做的最简单的事情就是类似sqlite的东西。这将使循环更加复杂,您必须首先检查数据库以查看是否执行了特定的计算。但是这已经比解析日志文件要好了,而且如果你正确地执行数据库模式和查询,速度会更快!好奇:会不会
    it.product(范围(1000)、范围(1000)、范围(1000))
    在内存中创建一个包含10亿项的列表?你对#2:如何暂停/恢复计算有什么想法?或者甚至停止并重新启动计算机,然后继续?您可以通过参数将与i、j、k相关的最后3个计算值传递给脚本,并使用产品迭代器,直到在开始计算之前找到它stuff@Basj,itertools创建了一个迭代器,因此它不会用这些项加载内存,而是按如下方式计算它们needed@Basj,然后,不要在开始时写日志,只要在作业完成时记录日志即可。
    the_args = it.product(range(100), range(100), range(100))
    #skip previously computed 
    while True:
        if next(the_args) == (i, j, k):
            break
    ...