Python 并行调用map的最简单方法?

Python 并行调用map的最简单方法?,python,python-3.x,parallel-processing,Python,Python 3.x,Parallel Processing,嘿,我有一些Python代码,它基本上是一个带有播放器对象的世界对象。在某一点上,所有玩家都了解了世界的现状,需要返回一个动作。玩家所做的计算是独立的,只使用各自玩家实例的实例变量 while True: #do stuff, calculate state with the actions array of last iteration for i, player in enumerate(players): actions[i] = player.get_ac

嘿,我有一些Python代码,它基本上是一个带有播放器对象的世界对象。在某一点上,所有玩家都了解了世界的现状,需要返回一个动作。玩家所做的计算是独立的,只使用各自玩家实例的实例变量

while True:
    #do stuff, calculate state with the actions array of last iteration
    for i, player in enumerate(players):
        actions[i] = player.get_action(state)

为循环并行运行内部
的最简单方法是什么?或者这是一个比我想象的更大的任务吗?

最直接的方法是使用(它的工作原理与
映射
):

但是请注意,这使用了多个进程。在Python中无法执行多线程处理,原因是

通常,并行化是通过线程完成的,线程可以访问程序中的相同数据(因为它们在同一进程中运行)。要在进程之间共享数据,需要使用IPC(进程间通信)机制,如管道、套接字、文件等,这会消耗更多资源。此外,生成进程比生成线程慢得多

其他解决办法包括:

  • 矢量化:将算法重写为向量和矩阵的计算,并使用硬件加速库执行
  • 使用另一个没有GIL的Python发行版
  • 用另一种语言实现并行代码并从Python调用它

当您必须在进程/线程之间共享数据时,会出现一个大问题。例如,在代码中,每个任务都将访问
操作
。如果您必须共享状态,欢迎使用,这是一项更大的任务,也是软件中最难正确完成的任务之一。

除了使用
多处理
?@IgnacioVazquez Abrams我问过关于在IRC(freenode#python)上只使用多处理模块的池对象及其映射函数,他们告诉我这并不容易。如果您想提供一个简短的工作示例,说明您是如何想象自己真的会在这方面有所帮助的——如果您的代码已经在工作,并且您通过分析发现这一点是一个瓶颈,那么您应该担心如何使这一点并行。否则,您可能会因为一些您可能根本不需要的东西而过早地进行优化。请看一下joblib,它的名称与简单的映射非常相似,谢谢!使用多个进程有什么不好的地方?多个进程也需要将全局数据放在其他进程中,除非您显式地同步这些数据,否则这些数据将发生分歧。如果没有全局数据要由这些函数检查(并且没有大的数据结构要传递给它们),多个进程将为您工作。在这种情况下,您甚至可以使用“lelo”:@jsbueno有没有办法防止每个进程复制例如World对象?实际上,每个进程只需要一个玩家对象实例和传递的参数来获取_action,不需要访问其他玩家对象或世界对象,我想如果每个进程只复制整个环境,这将是一个开销。防止这种情况发生的唯一方法是采用其他解决方案吗?一种“用另一种语言实现并行代码”的好方法是使用Cython作为“其他语言”—您可以编写主要是Python的代码并手动释放GIL—在这种情况下,您可以使用线程并利用并行性。
import multiprocessing
pool = multiprocessing.Pool()

def do_stuff(player):
    ...  # whatever you do here is executed in another process

while True:
    pool.map(do_stuff, players)