【问题标题】:Python timing code incorrect when calling parallel module - my code or the module?调用并行模块时Python计时代码不正确-我的代码还是模块?
【发布时间】:2014-02-28 20:56:14
【问题描述】:

我有一些运行数学模拟的代码,并对其计时。

当我在不使用多线程的情况下运行此代码时,计时代码运行良好。

当我使用多线程运行代码时;时间太短了 - 使用手表,我估计它比实际代码运行所需的时间快 4-8 倍。 (代码运行大约需要 12 秒,time 模块说 1.5-2.5 秒)

简化代码:(控制流程在下面稍微详细解释)

class GenX:

    def log_results(self, solver):

            time2 = time.clock()
            print '%0.3f' % time2 - self.time1
            ^
            ##### this value is incorrect ###########

    def __init__(self):
        self.time1 = time.clock()

        mySimulation.setup()
        mySimulation.OnceCompleteCall(log_results)

        ## (in reality both setup and start are more complicated)

    def optimize(self):
        mySimulation.start()
        return

我有另一个类实例化这个 GenX 类,然后运行 ​​GenX.optimize(),开始模拟。

模拟是一个单独的模块,在内部处理线程代码(它也是一个 1000 行的类,其中大约 50% 是不必要的 getter/setter ......所以我认为作者很可能是问题的根源)

一旦模拟完成,它会调用 log_results,它会计算所用时间 - 这是不正确的。

目前我不知道错误的来源是我的代码还是我正在使用的模块。

我检查了模块的作者在完成并行操作时调用了pool.join() - 它确实被调用了,但时间仍然不正确。

【问题讨论】:

  • join 到工作线程阻塞直到它们完成吗?
  • 是的 - 该函数确实被处理多处理代码的模块调用。我已经更新了问题。
  • 您是否尝试打印 self.time1 更改的所有地方?另外我建议您创建一个装饰器@timer,并检查您在每个步骤上花费了多少时间。
  • 对于程序的每次运行,self.time1 只分配一次——在上面的代码中看到的阶段。它没有在其他任何地方修改。我个人还不熟悉装饰器,而且时序代码并不重要,所以我通过简单地根据经验确定它大约是 5 倍并乘以它来近似它,现在应该这样做......虽然这有点hacky!

标签: python multithreading parallel-processing multiprocessing


【解决方案1】:

根据您拥有的线程数、CPU 一次处理的线程数以及线程在做什么,我认为这与以下问题有关:https://codereview.stackexchange.com/a/26669。可能是因为时钟只是测量处理时间而不是挂钟时间,所以你得到的值低于你的预期。

尝试使用 time.time() 代替。

【讨论】:

    猜你喜欢
    • 2023-01-26
    • 2016-06-21
    • 1970-01-01
    • 2012-12-16
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    相关资源
    最近更新 更多