如何在此 for 循环中实现多线程?

How can I implement multithreading in this for loop?

考虑这个代码片段

from tqdm import trange


def main_game(depth1, depth2):
    # some operator with complexity O(20^max(depth1,depth2))
    return depth1+depth2


DEPTH_MAX = 5
total = 0
for depth1 in range(1, DEPTH_MAX + 1):
    for depth2 in range(1, DEPTH_MAX + 1):
        for i in trange(100):
            total += main_game(depth1, depth2)

print(total)

我在 main_game() 中使用 minimax 算法,分支因子 = 10

现在,由于第三个 for 循环有一个耗时函数(时间复杂度高达 100*O(20^5)),有什么办法可以使它 运行 更快?我正在考虑并行化(例如多线程)。有什么建议吗?

使用 multiprocessing,然后从那里 Pool().starmap()starmap() 以并行方式为您的函数提供准备好的参数元组。并同步收集结果。 如果结果的顺序无关紧要,您可以使用异步版本 .starmap_async().get().

还有 Pool().apply()Pool.map()_async() 版本,但实际上你只需要学习 Pool().starmap()。这只是一些语法差异。

import multiprocessing as mp
n_cpu = mp.cpu_count()

# let's say your function is a diadic function (takes two arguments)
def main_game(depth1, depth2):
    return depth1 + depth2

DEPTH_MAX = 5
depths = list(range(1, DEPTH_MAX + 1))

# let's pre-prepare the arguments - because that goes fast!
depth1_depth2_pairs = [(d1, d2) for d1 in depths for d2 in depths]

# 1: Init multiprocessing.Pool()
pool = mp.Pool(n_cpu)
# 2: pool.starmap()
results = pool.starmap(main_game, depth_1_depth_2_pairs)
# 3: pool.close()
pool.close()

total = sum(results) # this does your `total +=`

## in this case, you could even use
results = pool.starmap_async(main_game, depth_1_depth_2_pairs).get()
## because the order doesn't matter, if you sum them all up
## which is commutative.

你可以使用 with 构造稍微好一点(它会自动关闭,即使发生错误,所以它不仅可以节省你的输入,而且更安全。

import multiprocessing as mp

n_cpu = mp.cpu_count()

def main_game(depth1, depth2):
    return depth1 + depth2

DEPTH_MAX = 5
depths = range(1, DEPTH_MAX + 1)
depth1_depth2_pairs = [(d1, d2) for d1 in depths for d2 in depths]

with mp.Pool(n_cpu) as pool:
    results = pool.starmap_async(main_game, depth_1_depth_2_pairs).get()

total = sum(results)