反转后 Numpy 乘法慢得多
Numpy multiplication much slower after reversal
我正在将两个 numpy 数组相乘:
import numpy as np
X = np.random.randn(4500,3500)
v = np.random.randn(3500,200)
默认都是C_CONTIGUOUS:
X.flags
# C_CONTIGUOUS : True
v.flags
# C_CONTIGUOUS : True
而且乘法很快:
%timeit X @ v
# 41 ms ± 2.54 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
但是,如果我反转 X 数组,就会发生奇怪的事情:
%timeit X[::-1,::-1] @ v
# 3.97 s ± 54.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
问题:
- This post 表示返回操作创建视图。结果视图既不是 C_CONTIGUOUS 也不是 F_CONTIGUOUS。这是什么意思?
X[::-1,::-1].flags
# C_CONTIGUOUS : False
# F_CONTIGUOUS : False
- 为什么反转操作会如此严重地减慢乘法?
A c_contiguous 数组是一个数组,表示为对连续缓冲区的行优先扫描。当您创建一个反向视图数组时,情况不再如此,因此数组不再是 c_contiguous.
至于为什么在反向数组上操作速度较慢,像这样的计算细节通常会因系统的 BLAS/LAPACK 安装而异。在这种情况下,我怀疑您的 BLAS 安装针对连续缓冲区上的矩阵乘积的常见情况优化了代码路径,并且没有针对不太常见的非连续缓冲区上的操作优化代码路径。
的确,运行 这在一台机器上使用了针对 ubuntu 的 libblas 构建的 numpy 给出了以下内容:
%timeit X @ v
# 1 loop, best of 3: 200 ms per loop
%timeit X[::-1,::-1] @ v
# 1 loop, best of 3: 4.64 s per loop
而 运行 在带有针对 MKL 构建的 numpy 的机器上显示不同的行为:
%timeit X @ v
# 92.6 ms ± 1.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit X[::-1,::-1] @ v
# 128 ms ± 2.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
(不同的 IPython 版本占不同的 %timeit
输出)
我正在将两个 numpy 数组相乘:
import numpy as np
X = np.random.randn(4500,3500)
v = np.random.randn(3500,200)
默认都是C_CONTIGUOUS:
X.flags
# C_CONTIGUOUS : True
v.flags
# C_CONTIGUOUS : True
而且乘法很快:
%timeit X @ v
# 41 ms ± 2.54 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
但是,如果我反转 X 数组,就会发生奇怪的事情:
%timeit X[::-1,::-1] @ v
# 3.97 s ± 54.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
问题:
- This post 表示返回操作创建视图。结果视图既不是 C_CONTIGUOUS 也不是 F_CONTIGUOUS。这是什么意思?
X[::-1,::-1].flags
# C_CONTIGUOUS : False
# F_CONTIGUOUS : False
- 为什么反转操作会如此严重地减慢乘法?
A c_contiguous 数组是一个数组,表示为对连续缓冲区的行优先扫描。当您创建一个反向视图数组时,情况不再如此,因此数组不再是 c_contiguous.
至于为什么在反向数组上操作速度较慢,像这样的计算细节通常会因系统的 BLAS/LAPACK 安装而异。在这种情况下,我怀疑您的 BLAS 安装针对连续缓冲区上的矩阵乘积的常见情况优化了代码路径,并且没有针对不太常见的非连续缓冲区上的操作优化代码路径。
的确,运行 这在一台机器上使用了针对 ubuntu 的 libblas 构建的 numpy 给出了以下内容:
%timeit X @ v
# 1 loop, best of 3: 200 ms per loop
%timeit X[::-1,::-1] @ v
# 1 loop, best of 3: 4.64 s per loop
而 运行 在带有针对 MKL 构建的 numpy 的机器上显示不同的行为:
%timeit X @ v
# 92.6 ms ± 1.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit X[::-1,::-1] @ v
# 128 ms ± 2.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
(不同的 IPython 版本占不同的 %timeit
输出)