繁体   English   中英

Python:并行执行内部具有顺序循环的函数

[英]Python: parallel execution of a function which has a sequential loop inside

我正在从 Sutton 和 Barto 的书Reinforcement Learning: An Introduction 中复制一些简单的 10 臂老虎机实验。 其中一些需要大量的计算时间,因此我试图利用多核 CPU 的优势。

这是我需要运行 2000 次的函数。 它有 1000 个连续步骤,可逐步提高奖励:

import numpy as np

def foo(eps): # need an (unused) argument to use pool.map()
    # initialising
    # the true values of the actions
    q = np.random.normal(0, 1, size=10)
    # the estimated values
    q_est = np.zeros(10)
    # the counter of how many times each of the 10 actions was chosen
    n = np.zeros(10)

    rewards = []
    for i in range(1000):
        # choose an action based on its estimated value
        a = np.argmax(q_est)
        # get the normally distributed reward 
        rewards.append(np.random.normal(q[a], 1)) 
        # increment the chosen action counter
        n[a] += 1 
        # update the estimated value of the action
        q_est[a] += (rewards[-1] - q_est[a]) / n[a] 
    return rewards

我执行这个函数 2000 次来得到 (2000, 1000) 数组:

reward = np.array([foo(0) for _ in range(2000)])

然后我绘制了 2000 次实验的平均奖励:

import matplotlib.pyplot as plt
plt.plot(np.arange(1000), reward.mean(axis=0))

顺序图

这完全符合预期的结果(看起来和书中的一样)。 但是当我尝试并行执行它时,我得到的平均奖励的标准偏差要大得多:

import multiprocessing as mp
with mp.Pool(mp.cpu_count()) as pool:
    reward_p = np.array(pool.map(foo, [0]*2000))
plt.plot(np.arange(1000), reward_p.mean(axis=0))

平行图

我想这是由于 foo 内部循环的并行化。 当我减少分配给任务的内核数量时,奖励图接近预期的形状。

有没有办法在获得正确结果的同时获得多处理的优势?

UPD:我尝试在 Windows 10 和顺序与并行上运行相同的代码,结果是一样的! 可能是什么原因?

Ubuntu 20.04、Python 3.8.5、jupyter

Windows 10、Python 3.7.3、jupyter

我们发现它在 windows 和 ubuntu 上是不同的。 大概是因为这个:

spawn 父进程启动一个新的python解释器进程。 子进程将只继承运行进程对象 run() 方法所需的资源。 特别是,父进程中不必要的文件描述符和句柄将不会被继承。 与使用 fork 或 forkserver 相比,使用此方法启动进程相当慢。

在 Unix 和 Windows 上可用。 Windows 和 macOS 上的默认设置。

fork 父进程使用 os.fork() 来 fork Python 解释器。 子进程在开始时实际上与父进程相同。 父进程的所有资源都由子进程继承。 请注意,安全地分叉多线程进程是有问题的。

仅在 Unix 上可用。 Unix 上的默认设置。

尝试将此行添加到您的代码中:

mp.set_start_method('spawn')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM