在python中使用多进程和numpy会显著降低速度
我为Q-learning算法编写了一个python代码,由于该算法具有随机输出,所以我必须多次运行它。因此,我使用了在python中使用多进程和numpy会显著降低速度,python,multithreading,performance,numpy,Python,Multithreading,Performance,Numpy,我为Q-learning算法编写了一个python代码,由于该算法具有随机输出,所以我必须多次运行它。因此,我使用了多处理模块。守则的结构如下: import numpy as np import scipy as sp import multiprocessing as mp # ...import other modules... # ...define some parameters here... # using multiprocessing result = [] num_thr
多处理
模块。守则的结构如下:
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秒,这个任务只占用1个线程,CPU使用率为100%(使用top
命令)
但是,如果我使用num_threads=3
(或更多)运行它,它将花费40秒以上的时间,并且此任务将占用3个线程,每个线程使用100%的CPU核心
我无法理解这种减速,因为在所有自定义函数中都没有并行化,也没有I/O操作。还值得注意的是,当num_threads=1
时,CPU使用率始终小于100%,但当num_threads
大于1时,CPU使用率有时可能为101%或102%
另一方面,我编写了另一个简单的测试文件,它不导入numpy和scipy,那么这个问题就永远不会出现。我注意到了这个问题,我的问题似乎是由于
numpy
中某些方法的自动并行(例如dot
)。但如图所示,当我运行单个作业时,我看不到任何并行化。当使用多处理池时,所有参数和结果都通过pickle发送。这可能会占用大量处理器,而且非常耗时。这可能是你问题的根源,尤其是当你的论点和/或结果很大的时候。在这些情况下,Python可能比运行计算花费更多的时间来清理和取消清理数据
但是,
numpy
会在计算过程中释放全局解释器锁,因此,如果您的工作是numpy密集型的,您可以通过使用线程而不是多处理来加速它。这样可以避免酸洗步骤。查看此处了解更多详细信息:这是正常的,因为许多因素,上下文切换、消息传递的序列化不是免费的,也不是围绕GIL工作的,因此预计CPU密集型的事情会更慢。我还编写了一个shell脚本,一次提交多个作业,而不是使用多处理,它也有同样的问题。这是否也是由于你所描述的皮克勒@Matthlas Fripp当启动多个单独的作业时,我希望类似这样的“令人尴尬的并行”任务几乎是线性扩展的,例如,4个核上的4个作业应该与1个核上的1个作业同时完成。不应该有泡菜的问题。是否可能是内存不足?如果所有作业都需要比系统更多的内存,那么系统将开始交换到磁盘或使用压缩内存(Mac)。这可能会导致严重的速度减慢。正如我在图中所示,每个线程占用的内存空间不足1%,因此我认为内存足以完成此任务。事实上,虽然有多份工作,但他们是独立的,他们之间没有沟通。对不起,我在这方面是空白。从屏幕截图上看,您的代码似乎总是运行单线程。因此,并行任务之间似乎不存在处理器争用的可能性,因为您有大量可用的内核。由于它们不进行任何I/O操作,并且使用的内存相对较少,因此我也不希望出现磁盘或内存争用。您是否能够提供一个最低限度的示例来说明此问题,以便其他人可以对其进行故障排除?