如何在Python中进行并行编程?

2024-04-20 09:21:35 发布

您现在位置:Python中文网/ 问答频道 /正文

对于C++,我们可以使用OpenMP来进行并行编程;但是OpenMP对于Python来说是行不通的。如果我想并行我的python程序的某些部分,我应该怎么做?

守则的结构可被视为:

solve1(A)
solve2(B)

其中solve1solve2是两个独立的函数。如何将这类代码并行而不是按顺序运行,以减少运行时间? 希望有人能帮助我。非常感谢提前。 代码是:

def solve(Q, G, n):
    i = 0
    tol = 10 ** -4

    while i < 1000:
        inneropt, partition, x = setinner(Q, G, n)
        outeropt = setouter(Q, G, n)

        if (outeropt - inneropt) / (1 + abs(outeropt) + abs(inneropt)) < tol:
            break

        node1 = partition[0]
        node2 = partition[1]

        G = updateGraph(G, node1, node2)

        if i == 999:
            print "Maximum iteration reaches"
    print inneropt

其中setinner和setouter是两个独立的函数。那是我想平行的地方。。。


Tags: 函数代码ifabspartitiontolopenmpnode1
3条回答

您可以使用multiprocessing模块。在这种情况下,我可以使用一个处理池:

from multiprocessing import Pool
pool = Pool()
result1 = pool.apply_async(solve1, [A])    # evaluate "solve1(A)" asynchronously
result2 = pool.apply_async(solve2, [B])    # evaluate "solve2(B)" asynchronously
answer1 = result1.get(timeout=10)
answer2 = result2.get(timeout=10)

这将产生可以为您执行一般工作的进程。由于我们没有通过processes,它将为您计算机上的每个CPU核心生成一个进程。每个CPU核可以同时执行一个进程。

如果要将列表映射到单个函数,请执行以下操作:

args = [A, B]
results = pool.map(solve1, args)

不要使用线程,因为GIL锁定了python对象上的任何操作。

CPython使用全局解释器锁,使并行编程比C++ +/P>更有趣

本主题有几个有用的示例和挑战描述:

Python Global Interpreter Lock (GIL) workaround on multi-core systems using taskset on Linux?

这可以用Ray非常优雅地完成。

要并行化示例,需要使用@ray.remote装饰器定义函数,然后使用.remote调用它们。

import ray

ray.init()

# Define the functions.

@ray.remote
def solve1(a):
    return 1

@ray.remote
def solve2(b):
    return 2

# Start two tasks in the background.
x_id = solve1.remote(0)
y_id = solve2.remote(1)

# Block until the tasks are done and get the results.
x, y = ray.get([x_id, y_id])

multiprocessing模块相比,它有许多优点。

  1. 同样的代码将运行在多核机器以及一组机器上。
  2. 进程通过shared memory and zero-copy serialization高效地共享数据。
  3. 错误消息可以很好地传播。
  4. 这些函数调用可以组合在一起,例如

    @ray.remote
    def f(x):
        return x + 1
    
    x_id = f.remote(1)
    y_id = f.remote(x_id)
    z_id = f.remote(y_id)
    ray.get(z_id)  # returns 4
    
  5. 除了远程调用函数外,类还可以远程实例化为actors

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

相关问题 更多 >