【问题标题】:Unexpected and unintuitive behaviour with Numba PrangeNumba Prange 的意外和不直观的行为
【发布时间】:2021-04-15 15:03:39
【问题描述】:

正如GitHub issue 中总结的那样,当从 prange 语句缩减为切片时,Numba 会表现出一些非常不直观的行为。

考虑下面的代码,这是一个典型的并行化热循环。当计算的结果被缩减为如下的切片时,

@numba.njit(parallel=True)
def hot_loop():
    
    n=10000
    
    result = np.zeros((n*100), np.float32)
    for i in numba.prange(n):
        
        # Run computations
        res = np.random.rand(100,100) @ np.random.rand(100)
        
        # Store result
        result[i*100:(i+1)*100] += res
        
    return result

它比分配的数组慢得多,

@numba.njit(parallel=True)
def hot_loop():
    
    n=10000
    
    result = np.zeros((n*100), np.float32)
    for i in numba.prange(n):
        
        # Run computations
        res = np.random.rand(100,100) @ np.random.rand(100)
        
        # Store allocated array
        result[i*100:(i+1)*100] += np.random.rand(100)
        
    return result

我的 Intel I7 CPU 的结果是前者为 74 毫秒,后者为 974 微秒。文档中的任何地方或其他问题都没有提到这一点,但会显着影响您真正可以使用 prange 的内容。 IE。如果你在保存结果时遇到了巨大的瓶颈,你为什么要在 prange 中计算基于复杂数组的数学。

问题可能是不完全支持 prange 以这种方式减少到切片,但是,对于后一种情况似乎无关紧要 - 这是一种令人困惑且不直观的行为。

还有其他人有过这种行为的经历吗?

【问题讨论】:

  • 因为第二个版本没有使用res,优化器将其优化出来,没有被计算,因此加速了

标签: python numpy parallel-processing numba


【解决方案1】:

在第二个例子中,行

res = np.random.rand(100,100) @ np.random.rand(100)

计算未使用的变量res。如果删除该行,时间完全一样。

LLVM compiler 优化过程很可能正在检测未使用的变量并删除评估它所需的代码。

【讨论】:

    猜你喜欢
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 2011-12-15
    相关资源
    最近更新 更多