【问题标题】:Why is np.cumprod() slower than my own function for large arrays?为什么 np.cumprod() 比我自己的大型数组函数慢?
【发布时间】:2022-02-07 20:02:03
【问题描述】:

做了一些测试,我注意到我编写的自定义循环函数可能比 NumPy 内置函数 np.cumprod() 更快。我不认为这是可能的,有人可以解释发生了什么吗?

import time
import numpy as np

def custom_cumprod(x):
    xb = [1]
    for xi in x:
        xb.append(xb[-1]*xi)
    return np.array(xb[1:])

x = np.random.random((10000, 10000))

t0 = time.time()
b = custom_cumprod(x)
t1 = time.time()
print(t1-t0)
t0 = time.time()
c = np.cumprod(x,0)
t1 = time.time()
print(t1-t0)
print(np.sum(c-b))

谢谢!

【问题讨论】:

  • 可能 NumPy 选择了一个效率较低的循环顺序。
  • 您在内存不是contiguous 的轴上进行乘法运算。比较np.cumprod(x.T, 0)
  • 我检查了您的测试,发现内部 cumprod 使用的内存明显减少。我想这是选择了更节省内存的方法,但它是以速度为代价的。
  • 我过去问过类似的问题。简而言之,(1)np.cumprod(x, 1) 由于内存布局会更快,(2)你的数据太大了,你基本上测试了你的电脑的内存效率 - 100x100 numpy 应该更快。

标签: python numpy time


【解决方案1】:

问题是计算沿着外部维度运行,numpy 似乎没有优化这种情况。沿着这个维度循环,内存中的值是不连续的,导致缓存和TLB未命中。

这可以通过以 Fortran 顺序 (np.asfortranarray) 存储数组,或转置并沿内部维度运行计算来解决。

perf 清楚地显示了差异:

perf stat -e LLC-load-misses,dTLB-load-misses python3 -c \
    'import numpy as np; np.cumprod(np.random.random((10000, 10000)), axis=0)'

 Performance counter stats for 'python3 -c import numpy as np; np.cumprod(np.random.random((10000, 10000)), axis=0)':

        22.254.639      LLC-load-misses:u                                           
       114.772.180      dTLB-load-misses:u                                          

       3,200727804 seconds time elapsed

       2,148422000 seconds user
       1,044664000 seconds sys

perf stat -e LLC-load-misses,dTLB-load-misses python3 -c \
    'import numpy as np; np.cumprod(np.random.random((10000, 10000)), axis=1)'

 Performance counter stats for 'python3 -c import numpy as np; np.cumprod(np.random.random((10000, 10000)), axis=1)':

           633.959      LLC-load-misses:u                                           
         2.485.725      dTLB-load-misses:u                                          

       2,276527365 seconds time elapsed

       0,947946000 seconds user
       1,316536000 seconds sys

理想情况下,numpy 应该以与您在自定义版本中相同的方式运行计算。

【讨论】:

    猜你喜欢
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    相关资源
    最近更新 更多