使用python

时间:2017-11-19 18:22:02

标签: python multithreading performance numpy

我为Q学习算法编写了一个python代码,我必须多次运行它,因为这个算法有随机输出。因此我使用multiprocessing模块。代码的结构如下

import numpy as np
import scipy as sp
import multiprocessing as mp
# ...import other modules...

# ...define some parameters here...

# using multiprocessing
result = []
num_threads = 3
pool = mp.Pool(num_threads)
for cnt in range(num_threads):
    args = (RL_params+phys_params) # arguments
    result.append(pool.apply_async(Q_learning, args))

pool.close()
pool.join()

我的代码中没有I / O操作,我的工作站有6个内核(12个线程)和足够的内存用于此作业。当我使用num_threads=1运行代码时,它只需要13秒,此任务仅占用CPU使用率为100%的1个线程(使用top命令)。

click to see picture of CPU status

但是,如果我使用num_threads=3(或更多)运行它,它将需要超过40秒,并且此任务将占用3个线程,每个线程使用100%CPU核心。

click to see picture of CPU status

我无法理解这种放慢速度,因为所有自定义函数都没有并行化,也没有I / O操作。值得注意的是,当num_threads=1时,CPU使用率始终低于100%,但当num_threads大于1时,CPU使用率有时可能为101%或102%。

另一方面,我写了另一个简单的测试文件,它没有导入numpy和scipy,然后这个问题从未显示过。我注意到了这个问题why isn't numpy.mean multithreaded?,似乎我的问题是由于numpy中某些方法的自动并行化(例如dot)。但正如我在图片中所示,当我开展一份工作时,我看不到任何并行化。

1 个答案:

答案 0 :(得分:1)

使用多处理池时,所有参数和结果都通过pickle发送。这可能是处理器密集型且耗时的。这可能是您问题的根源,特别是如果您的参数和/或结果很大。在这些情况下,与运行计算相比,Python可能花费更多时间来挑选和取消数据。

但是,numpy在计算期间释放全局解释器锁,因此如果您的工作是密集型的,您可以通过使用线程而不是多处理来加快速度。那样可以避免酸洗步骤。有关详情,请参阅此处:https://stackoverflow.com/a/38775513/3830997