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 函数)。
我正在使用 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 函数)。