有人可以解释一下,为什么numpy.einsum('ij,ji',A,B)比numpy.einsum('ij,ij',A,B)慢得多,如下所示?
In [1]: import numpy as np
In [2]: a = np.random.rand(1000,1000)
In [3]: b = np.random.rand(1000,1000)
In [4]: timeit np.einsum('ij,ij', a, b)
532 µs ± 5.36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [5]: timeit np.einsum('ij,ji', a, b)
1.28 ms ± 20.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
关于, 马雷克
答案 0 :(得分:2)
第一嫌疑犯:https://en.wikipedia.org/wiki/Locality_of_reference#Spatial_and_temporal_locality_usage
在第一种情况下,a
和b
的内存都以连续的顺序模式进行访问。
在第二种情况下,b
的内存在内部循环中以1000个元素(8000字节)的步幅进行访问。
大多数现代x86处理器都具有32KiB L1高速缓存和64字节高速缓存行,这意味着总共有512个高速缓存行。因此,整个L1缓存在外循环迭代之间被驱逐了两次。
请注意,如果您运行
timeit np.einsum('ij,ji', a, b.T)
您应该获得与第一个示例大致相同的时间。
类似地
timeit np.einsum('ij,ij', a, b.T)
应该给您第二个示例相同的时间。