为什么 numpy/scipy 在没有 OpenBLAS 的情况下更快?
Why numpy/scipy is faster without OpenBLAS?
我安装了两个:
brew install numpy
(和scipy)--with-openblas
- 克隆 GIT 个存储库(用于 numpy 和 scipy)并自行构建
在我克隆了两个方便的脚本以在多线程环境中验证这些库之后:
git clone https://gist.github.com/3842524.git
然后对于我正在执行的每个安装 show_config
:
python -c "import scipy as np; np.show_config()"
安装1一切顺利:
lapack_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/opt/openblas/lib']
language = f77
blas_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/opt/openblas/lib']
language = f77
openblas_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/opt/openblas/lib']
language = f77
blas_mkl_info:
NOT AVAILABLE
但是安装2的东西不是那么亮:
lapack_opt_info:
extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
extra_compile_args = ['-msse3']
define_macros = [('NO_ATLAS_INFO', 3)]
blas_opt_info:
extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
extra_compile_args = ['-msse3', '- I/System/Library/Frameworks/vecLib.framework/Headers']
define_macros = [('NO_ATLAS_INFO', 3)]
看来我未能正确 link OpenBLAS。但现在还好,这是性能结果。所有测试均在 iMac、Yosemite、i7-4790K、4 核、超线程上进行。
首次使用 OpenBLAS 安装:
numpy:
OMP_NUM_THREADS=1 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.126578998566 sec
OMP_NUM_THREADS=2 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.0640147686005 sec
OMP_NUM_THREADS=4 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.0360922336578 sec
OMP_NUM_THREADS=8 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.0364527702332 sec
scipy:
OMP_NUM_THREADS=1 python test_scipy.py
cholesky: 0.0276656150818 sec
svd: 0.732437372208 sec
OMP_NUM_THREADS=2 python test_scipy.py
cholesky: 0.0182101726532 sec
svd: 0.441690778732 sec
OMP_NUM_THREADS=4 python test_scipy.py
cholesky: 0.0130400180817 sec
svd: 0.316107988358 sec
OMP_NUM_THREADS=8 python test_scipy.py
cholesky: 0.012854385376 sec
svd: 0.315939807892 sec
没有 OpenBLAS 的第二次安装:
numpy:
OMP_NUM_THREADS=1 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0371072292328 sec
OMP_NUM_THREADS=2 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0215149879456 sec
OMP_NUM_THREADS=4 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0146862030029 sec
OMP_NUM_THREADS=8 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0141334056854 sec
scipy:
OMP_NUM_THREADS=1 python test_scipy.py
cholesky: 0.0109382152557 sec
svd: 0.32529540062 sec
OMP_NUM_THREADS=2 python test_scipy.py
cholesky: 0.00988121032715 sec
svd: 0.331357002258 sec
OMP_NUM_THREADS=4 python test_scipy.py
cholesky: 0.00916676521301 sec
svd: 0.318637990952 sec
OMP_NUM_THREADS=8 python test_scipy.py
cholesky: 0.00931282043457 sec
svd: 0.324427986145 sec
令我惊讶的是,第二种情况比第一种情况更快。在 scipy 的情况下,添加更多内核后性能没有提高,但即使是一个内核也比 OpenBLAS 中的 4 个内核快。
有人知道这是为什么吗?
有两个明显的差异可能会导致差异:
您正在比较两个不同版本的 numpy。您使用 Homebrew 安装的 OpenBLAS 链接版本是 1.9.1,而您从源代码构建的版本是 1.10.0.dev0+3c5409e。
虽然较新的版本没有链接到 OpenBLAS,但它链接到 Apple 的 Accelerate Framework,一个不同的优化 BLAS 实现。
第二种情况你的测试脚本仍然报告 slow blas
的原因是与最新版本的 numpy 不兼容。您正在使用的脚本测试 numpy 是否通过 checking for the presence of numpy.core._dotblas
:
链接到优化的 BLAS 库
try:
import numpy.core._dotblas
print 'FAST BLAS'
except ImportError:
print 'slow blas'
在旧版本的 numpy 中,如果找到优化的 BLAS 库,此 C 模块只会在安装过程中编译。但是,_dotblas
has been removed altogether in development versions > 1.10.0 (as mentioned in ),因此脚本将始终报告这些版本的 slow blas
。
我已经编写了 numpy 测试脚本的更新版本,可以正确报告最新版本的 BLAS 链接; you can find it here.
我安装了两个:
brew install numpy
(和scipy)--with-openblas
- 克隆 GIT 个存储库(用于 numpy 和 scipy)并自行构建
在我克隆了两个方便的脚本以在多线程环境中验证这些库之后:
git clone https://gist.github.com/3842524.git
然后对于我正在执行的每个安装 show_config
:
python -c "import scipy as np; np.show_config()"
安装1一切顺利:
lapack_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/opt/openblas/lib']
language = f77
blas_opt_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/opt/openblas/lib']
language = f77
openblas_info:
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/opt/openblas/lib']
language = f77
blas_mkl_info:
NOT AVAILABLE
但是安装2的东西不是那么亮:
lapack_opt_info:
extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
extra_compile_args = ['-msse3']
define_macros = [('NO_ATLAS_INFO', 3)]
blas_opt_info:
extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
extra_compile_args = ['-msse3', '- I/System/Library/Frameworks/vecLib.framework/Headers']
define_macros = [('NO_ATLAS_INFO', 3)]
看来我未能正确 link OpenBLAS。但现在还好,这是性能结果。所有测试均在 iMac、Yosemite、i7-4790K、4 核、超线程上进行。
首次使用 OpenBLAS 安装:
numpy:
OMP_NUM_THREADS=1 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.126578998566 sec
OMP_NUM_THREADS=2 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.0640147686005 sec
OMP_NUM_THREADS=4 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.0360922336578 sec
OMP_NUM_THREADS=8 python test_numpy.py
FAST BLAS
version: 1.9.2
maxint: 9223372036854775807
dot: 0.0364527702332 sec
scipy:
OMP_NUM_THREADS=1 python test_scipy.py
cholesky: 0.0276656150818 sec
svd: 0.732437372208 sec
OMP_NUM_THREADS=2 python test_scipy.py
cholesky: 0.0182101726532 sec
svd: 0.441690778732 sec
OMP_NUM_THREADS=4 python test_scipy.py
cholesky: 0.0130400180817 sec
svd: 0.316107988358 sec
OMP_NUM_THREADS=8 python test_scipy.py
cholesky: 0.012854385376 sec
svd: 0.315939807892 sec
没有 OpenBLAS 的第二次安装:
numpy:
OMP_NUM_THREADS=1 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0371072292328 sec
OMP_NUM_THREADS=2 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0215149879456 sec
OMP_NUM_THREADS=4 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0146862030029 sec
OMP_NUM_THREADS=8 python test_numpy.py
slow blas
version: 1.10.0.dev0+3c5409e
maxint: 9223372036854775807
dot: 0.0141334056854 sec
scipy:
OMP_NUM_THREADS=1 python test_scipy.py
cholesky: 0.0109382152557 sec
svd: 0.32529540062 sec
OMP_NUM_THREADS=2 python test_scipy.py
cholesky: 0.00988121032715 sec
svd: 0.331357002258 sec
OMP_NUM_THREADS=4 python test_scipy.py
cholesky: 0.00916676521301 sec
svd: 0.318637990952 sec
OMP_NUM_THREADS=8 python test_scipy.py
cholesky: 0.00931282043457 sec
svd: 0.324427986145 sec
令我惊讶的是,第二种情况比第一种情况更快。在 scipy 的情况下,添加更多内核后性能没有提高,但即使是一个内核也比 OpenBLAS 中的 4 个内核快。
有人知道这是为什么吗?
有两个明显的差异可能会导致差异:
您正在比较两个不同版本的 numpy。您使用 Homebrew 安装的 OpenBLAS 链接版本是 1.9.1,而您从源代码构建的版本是 1.10.0.dev0+3c5409e。
虽然较新的版本没有链接到 OpenBLAS,但它链接到 Apple 的 Accelerate Framework,一个不同的优化 BLAS 实现。
第二种情况你的测试脚本仍然报告 slow blas
的原因是与最新版本的 numpy 不兼容。您正在使用的脚本测试 numpy 是否通过 checking for the presence of numpy.core._dotblas
:
try:
import numpy.core._dotblas
print 'FAST BLAS'
except ImportError:
print 'slow blas'
在旧版本的 numpy 中,如果找到优化的 BLAS 库,此 C 模块只会在安装过程中编译。但是,_dotblas
has been removed altogether in development versions > 1.10.0 (as mentioned in slow blas
。
我已经编写了 numpy 测试脚本的更新版本,可以正确报告最新版本的 BLAS 链接; you can find it here.