我的代码中有我要并行化的循环
from numba import njit, prange
from time import time
@njit
def f1(n):
s = 0
for i in range(n):
for j in range(n):
for k in range(n):
s += (i * k < j * j) - (i * k > j * j)
return s
@njit
def f2(n):
s = 0
for i in prange(n):
for j in prange(n):
for k in prange(n):
s += (i * k < j * j) - (i * k > j * j)
return s
@njit(parallel=True)
def f3(n):
s = 0
for i in range(n):
for j in range(n):
for k in range(n):
s += (i * k < j * j) - (i * k > j * j)
return s
@njit(parallel=True)
def f4(n):
s = 0
for i in prange(n):
for j in prange(n):
for k in prange(n):
s += (i * k < j * j) - (i * k > j * j)
return s
for f in [f1, f2, f3, f4]:
d = time()
f(2500)
print('%.02f' % (time() - d))
我得到了时间:
27.44
27.34
26.83
13.05
我检查了我的处理器的活动,虽然前三个功能是100%,但第四个功能是~300%。
我不明白为什么指定并行没有改变任何东西而且需要使用prange。在the doc中,有一个范围示例。
答案 0 :(得分:1)
来自Numba文件:
@jit的实验parallel = True选项将尝试优化数组操作并并行运行它们。它还增加了对prange()的支持,以显式并行化循环。
既然你没有在你的函数中做任何数组操作,那么Numba没有任何东西可以并行化而没有用prange明确标记循环。
所以只是为了确保没有混乱。 当你在装饰中设置parallel = True时,Numba只会将你的循环分成线程,并通过改变来明确地标记循环;范围 - &gt; PRANGE。
在你的f4()中你已经把prange放在了所有的for循环中,我建议只把prange放在最外面的循环上,因为你不想冒险从线程中产生线程。 即:
@njit(parallel=True)
def f5(n):
s = 0
for i in prange(n):
for j in range(n):
for k in range(n):
s += (i * k < j * j) - (i * k > j * j)
return s
答案 1 :(得分:0)
我在Github上创建了一个问题,贡献者非常准确地回答了问题(https://github.com/numba/numba/issues/2960#issuecomment-388767318)。
如果他想在这里重新发表答案,我会接受。