gpt4 book ai didi

python - 带有 ThreadPoolExecutor 的 Cython nogil 没有提供加速

转载 作者:太空宇宙 更新时间:2023-11-03 10:51:44 24 4
gpt4 key购买 nike

我假设如果我使用 nogil 指令在 Cython 中编写我的代码,那确实会绕过 gil,我可以使用 ThreadPoolExecutor 来使用多个核心。或者,更有可能的是,我在实现过程中搞砸了一些事情,但我似乎无法弄清楚是什么。

我已经使用 Barnes-Hut 算法编写了一个简单的 n 体模拟,并希望并行进行查找:

# cython: boundscheck=False
# cython: wraparound=False
...

def estimate_forces(self, query_point):
...
cdef np.float64_t[:, :] forces

forces = np.zeros_like(query_point, dtype=np.float64)
estimate_forces_multiple(self.root, query_point.data, forces, self.theta)

return np.array(forces, dtype=np.float64)


cdef void estimate_forces_multiple(...) nogil:
for i in range(len(query_points)):
...
estimate_forces(cell, query_point, forces, theta)

我这样调用代码:

data = np.random.uniform(0, 100, (1000000, 2))

executor = ThreadPoolExecutor(max_workers=max_workers)

quad_tree = QuadTree(data)

chunks = np.array_split(data, max_workers)
forces = executor.map(quad_tree.estimate_forces, chunks)
forces = np.vstack(list(forces))

为了使相关代码更清晰,我省略了很多代码。据我了解,增加 max_workers 应该使用多个内核并提供显着的加速,但是,情况似乎并非如此:

> time python barnes_hut.py --max-workers 1
python barnes_hut.py 9.35s user 0.61s system 106% cpu 9.332 total

> time python barnes_hut.py --max-workers 2
python barnes_hut.py 9.05s user 0.64s system 107% cpu 9.048 total

> time python barnes_hut.py --max-workers 4
python barnes_hut.py 9.08s user 0.64s system 107% cpu 9.035 total

> time python barnes_hut.py --max-workers 8
python barnes_hut.py 9.12s user 0.71s system 108% cpu 9.098 total

构建四叉树用时不到 1 秒,因此大部分时间花在 estimate_forces_multiple 上,但很明显,使用多线程并没有加快我的速度。查看top,它似乎也没有使用多核。

我的猜测是我一定错过了一些非常重要的东西,但我真的不知道是什么。

最佳答案

我遗漏了一个实际上发出释放 GIL 信号的关键部分:

def estimate_forces(self, query_point):
...
cdef np.float64_t[:, :] forces

forces = np.zeros_like(query_point, dtype=np.float64)
# HERE
cdef DTYPE_t[:, :] query_points = query_point.data
with nogil:
estimate_forces_multiple(self.root, query_points, forces, self.theta)

return np.array(forces, dtype=np.float64)

我还发现 UNIX time 命令对多线程程序没有执行我想要的操作并且报告了相同的数字(我猜它报告了 CPU 时间?)。使用 pythons timeit 提供了预期的结果:

max_workers=1: 91.2366s
max_workers=2: 36.7975s
max_workers=4: 30.1390s
max_workers=8: 24.0240s

关于python - 带有 ThreadPoolExecutor 的 Cython nogil 没有提供加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49047255/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com