Numba 是否需要在每个并行进程中单独编译?

Does Numba need to compile separately within each parallel process?

我正在使用 numba 的 @njit 装饰器来编译一个在并行进程中使用的函数,但它比我预期的要慢。本应在执行时间上相差一个数量级的进程大约花费相同的时间,这使得编译开销看起来很大。

我有一个功能

@njit
def foo(ar):
   (do something)
   return ar

和一个普通的python函数

def bar(x):
    (do something)
    return foo(x)

在类似

的并行进程中被调用
if __name__=="__main__":
    with concurrent.futures.ProcessPoolExecutor(max_workers=maxWorkers) as executor:
        results = executor.map(bar, args)  

其中 args 是一长串参数。 这是否意味着 foo() 在每个进程中单独编译?这可以解释额外的开销。对此有好的解决方案吗?我可以在生成进程之前对其中一个参数调用 foo() 一次,强制它提前编译。有没有更好的方法?

多处理导致生成的进程执行不在主要部分中的代码(即 if __name__ == "__main__")。这确实包括 Numba 函数的编译。 缓存 可用于编译一次函数并将其缓存,以便后续编译更快(代码可以从缓存中加载)假设函数上下文相同(例如参数类型) ,对全局变量的依赖,编译标志等)。此功能适用于 @nb.njit(cache=True)。有关此的更多信息,请阅读文档的 this 部分。在您的情况下,主进程将编译该函数,而其他进程将从缓存中加载它。

请注意,通常最好使用 Numba 的多线程功能而不是多处理,因为生成过程的成本更高(时间和内存使用方面)。也就是说,只能从多线程 Numba 上下文调用少数函数(主要是 Numpy 和 Numba 函数)。