numba没有并行化范围

时间:2018-05-09 13:51:54

标签: python jit numba

我的代码中有我要并行化的循环

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中,有一个范围示例。

2 个答案:

答案 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)。

如果他想在这里重新发表答案,我会接受。