我为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
)。但正如我在图片中所示,当我开展一份工作时,我看不到任何并行化。
答案 0 :(得分:1)
使用多处理池时,所有参数和结果都通过pickle
发送。这可能是处理器密集型且耗时的。这可能是您问题的根源,特别是如果您的参数和/或结果很大。在这些情况下,与运行计算相比,Python可能花费更多时间来挑选和取消数据。
但是,numpy
在计算期间释放全局解释器锁,因此如果您的工作是密集型的,您可以通过使用线程而不是多处理来加快速度。那样可以避免酸洗步骤。有关详情,请参阅此处:https://stackoverflow.com/a/38775513/3830997