Python中的并行性

fma*_*ark 22 python parallel-processing multithreading message-passing

在Python中实现并行性有哪些选择?我想对一些非常大的栅格执行一堆CPU绑定计算,并希望将它们并行化.来自C背景,我熟悉三种并行方法:

  1. 消息传递过程,可能分布在集群中,例如MPI.
  2. 显式共享内存并行,使用pthreadsfork(),pipe()等.人
  3. 隐式共享内存并行,使用OpenMP.

决定使用方法是权衡利弊.

在Python中,有哪些方法可用,它们的特征是什么?是否有可群集的MPI克隆?实现共享内存并行性的首选方法是什么?我听说过GIL的问题,以及对tasklet的引用.

简而言之,在选择它们之前,我需要了解Python中的不同并行化策略?

Wil*_*ill 12

通常,您描述CPU绑定计算.这不是Python的强项.从历史上看,它们都不是多处理的.

主流Python解释器中的线程已被可怕的全局锁定所统治.新的多处理 API可以解决这个问题,并通过管道和队列等提供工作池抽象.

您可以用CCython编写性能关键代码,并使用Python作为粘合剂.


Edw*_*ale 5

新的(2.6)多处理模块是要走的路.它使用子进程来解决GIL问题.它还抽象出一些本地/远程问题,因此可以在以后选择在本地运行代码或在群集上分布.我上面链接的文档有点可以咀嚼,但应该提供一个良好的入门基础.


Rob*_*ara 5

Ray是一个用于执行此操作的优雅(且快速)的库。

并行化 Python 函数的最基本策略是使用装饰器声明函数@ray.remote。然后就可以异步调用了。

import ray
import time

# Start the Ray processes (e.g., a scheduler and shared-memory object store).
ray.init(num_cpus=8)

@ray.remote
def f():
    time.sleep(1)

# This should take one second assuming you have at least 4 cores.
ray.get([f.remote() for _ in range(4)])
Run Code Online (Sandbox Code Playgroud)

您还可以使用actor并行化有状态计算,再次使用@ray.remote装饰器。

# This assumes you already ran 'import ray' and 'ray.init()'.

import time

@ray.remote
class Counter(object):
    def __init__(self):
        self.x = 0

    def inc(self):
        self.x += 1

    def get_counter(self):
        return self.x

# Create two actors which will operate in parallel.
counter1 = Counter.remote()
counter2 = Counter.remote()

@ray.remote
def update_counters(counter1, counter2):
    for _ in range(1000):
        time.sleep(0.25)
        counter1.inc.remote()
        counter2.inc.remote()

# Start three tasks that update the counters in the background also in parallel.
update_counters.remote(counter1, counter2)
update_counters.remote(counter1, counter2)
update_counters.remote(counter1, counter2)

# Check the counter values.
for _ in range(5):
    counter1_val = ray.get(counter1.get_counter.remote())
    counter2_val = ray.get(counter2.get_counter.remote())
    print("Counter1: {}, Counter2: {}".format(counter1_val, counter2_val))
    time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

与多处理模块相比,它具有许多优点:

Ray是我一直帮助开发的一个框架。