在Python中实现并行性有哪些选择?我想对一些非常大的栅格执行一堆CPU绑定计算,并希望将它们并行化。来自C背景,我熟悉三种并行方法:
决定使用方法是权衡利弊。
在Python中,有哪些方法可用,它们的特点是什么?是否有可群集的 MPI 克隆?实现共享内存并行性的首选方法是什么?我听说过 GIL 的问题,以及对 tasklets 的引用。
简而言之,在选择它们之前,我需要了解Python中的不同并行化策略?
答案 0 :(得分:12)
通常,您描述CPU绑定计算。这不是Python的强项。从历史上看,它们都不是多处理的。
主流Python解释器中的线程已被可怕的全局锁定所统治。新的multiprocessing API可以解决这个问题,并提供带有管道和队列等的工作池抽象。
答案 1 :(得分:5)
新的(2.6)multiprocessing模块是可行的方法。它使用子进程来解决 GIL 问题。它还抽象出一些本地/远程问题,因此可以在以后选择在本地运行代码或在群集上分布。我上面链接的文档很容易咀嚼,但应该为开始提供良好的基础。
答案 2 :(得分:3)
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)])
您也可以再次使用@ray.remote
装饰器,使用actors并行化状态计算。
# 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)
与multiprocessing模块相比,它具有许多优点:
Ray是我一直在帮助开发的框架。
答案 3 :(得分:0)
答案 4 :(得分:0)
根据您需要处理多少数据以及您打算使用多少CPU /机器,在某些情况下,在C(或Java / C#中使用jython / IronPython)编写部分数据更好)
从中获得的加速可能比在8个CPU上并行运行更能提高性能。