numba没有并行化范围

Lab*_*abo 5 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))
Run Code Online (Sandbox Code Playgroud)

我得到的时间:

27.44
27.34
26.83
13.05
Run Code Online (Sandbox Code Playgroud)

我检查了我的处理器的活动,虽然前三个功能是100%,但第四个是~300%.

我不明白为什么指定parallel并没有改变任何东西而且需要使用prange.在doc中,有一个范围示例.

Eri*_*ren 1

来自 Numba 文档:

@jit 的实验性 parallel=True 选项将尝试优化数组操作并并行运行它们。它还添加了对 prange() 的支持以显式并行化循环。

现在,由于您不在函数中执行任何数组操作,因此如果不使用 prange 显式标记循环,Numba 就无法并行化。

所以只是为了确保没有混淆。仅当您在装饰中设置parallel=True 时,Numba 才会将循环拆分为线程,并通过更改显式标记循环;范围 -> 范围。

在您的 f4() 中,您已将 prange 放在所有 for 循环上,我建议仅将 prange 放在最外层循环上,因为您不想冒险从线程中生成线程。IE:

@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
Run Code Online (Sandbox Code Playgroud)