我正在尝试编写一个简单的示例来说明使用
以下是我的完整示例:
numba.prange
的好处,以便我和同事们更好地理解。但是,我无法得到有效的加速。我编写了一个简单的一维扩散求解器,它基本上循环遍历一个长数组,将元素i+1
、i
和i-1
组合起来,然后将结果写入第二个数组的元素i
中。这应该是一个非常适合并行for循环的完美用例,类似于Fortran或C中的OpenMP。以下是我的完整示例:
import numpy as np
from numba import jit, prange
@jit(nopython=True, parallel=True)
def diffusion(Nt):
alpha = 0.49
x = np.linspace(0, 1, 10000000)
# Initial condition
C = 1/(0.25*np.sqrt(2*np.pi)) * np.exp(-0.5*((x-0.5)/0.25)**2)
# Temporary work array
C_ = np.zeros_like(C)
# Loop over time (normal for-loop)
for j in range(Nt):
# Loop over array elements (space, parallel for-loop)
for i in prange(1, len(C)-1):
C_[i] = C[i] + alpha*(C[i+1] - 2*C[i] + C[i-1])
C[:] = C_
return C
# Run once to just-in-time compile
C = diffusion(1)
# Check timing
%timeit C = diffusion(100)
当使用parallel=False
运行时,需要约2秒钟,而使用parallel=True
则需要约1.5秒钟。我在MacBook Pro上运行,该计算机有4个物理核心,Activity Monitor报告在并行化和非并行化的情况下分别占用100%和约700%的CPU使用率。
我本来希望能够获得接近4倍的速度提升。我做错了什么吗?
parallel=False
,我得到了1.52秒的时间;使用parallel=True
,我得到了524毫秒的时间;使用parallel=True
并将其他范围更改为prange,我得到了326毫秒的时间。 - Nin17Nt
循环只会导致由于竞争条件而产生错误的结果。因此,在实践中这不是一个好主意。 - Jérôme Richard