NumPy在不同BLAS实现下的性能
在本文中,我们将介绍NumPy(Python中的数组计算库)在不同BLAS(基本线性代数子程序)实现下的性能表现。BLAS是一组通用的子程序,用于执行矢量和矩阵的算术和线性代数操作。NumPy使用BLAS来加速线性代数计算,并提高其性能。我们将比较不同BLAS实现的性能,并探究NumPy在高性能计算方面的优势。
阅读更多:Numpy 教程
BLAS实现
BLAS的几个实现,如下所示:
- OpenBLAS
- ATLAS
- Apple Accelerate Framework
- Intel MKL
- GotoBLAS
这些实现都采用优化的矩阵乘法算法,以加速NumPy中的线性代数计算。由于在不同平台和硬件上的性能差异,所以选择合适的BLAS实现是至关重要的。
性能测试
我们珂以使用下面的Python脚本测试NumPy在不同BLAS实现下的性能表现:
import numpy as np
from time import time
def run_test(n, b):
a = np.random.rand(n, n)
b = np.random.rand(n, n)
start_time = time()
np.dot(a, b, out=b)
end_time = time()
print(f"{b.shape[0]:6} {b.shape[1]:6} {end_time-start_time:.6f} {b.mean():.6f} {b.std():.6f} {b.var():.6f} {b.min():.6f} {b.max():.6f} {b.sum():.6f} {b.trace():.6f} {b.diagonal().sum():.6f}")
ns = [(2**i)*100 for i in range(11)]
for n in ns:
print(" n_rows n_cols time_mean time_std time_var min max m_sum m_trace m_diag_sum")
for b in ["openblas", "atlas", "accelerate", "mkl_rt"]:
if b == "openblas":
np.environ['OPENBLAS_NUM_THREADS'] ='1'
elif b == "atlas":
np.environ["ATLAS_NUM_THREADS"] = '1'
elif b == "accelerate":
np.environ["VECLIB_MAXIMUM_THREADS"] = '1'
elif b == "mkl_rt":
np.environ["MKL_NUM_THREADS"] = '1'
np.set_printoptions(formatter={'float_kind': "{:.6f}".format})
np.set_printoptions(precision=6, suppress=True)
np.random.seed(0)
np.show_config()
np.__config__.show()
np.__config__.blas_mkl_info()
print(b)
np.__config__.blas_config_info()
run_test(n, b)
该脚本在多个不同的2^1X2^k, k=0, 1, 2, …,11 squares矩阵上运行,默认情况下一次运行方法开三个线程。这个代码可以检测您的NumPy在何种BLAS实现上运行,以及检测您使用的线程数。
总结
在本文中,我们分享了NumPy在不同BLAS实现下的性能测试。我们比较了OpenBLAS,ATLAS,Apple Accelerate框架,Intel MKL和Goto BLAS等BLAS实现的性能表现,并探究了适当地选择BLAS实现的重要性。由于性能差异因硬件和平台而异,因此在选择BLAS实现时需要仔细权衡性能和可用性。我们还提供了一个简单的Python脚本,可以测试NumPy在不同BLAS实现下的性能表现,以及确定您正在使用的线程数和BLAS实现。我们希望这个信息能够帮助您更好地使用NumPy和BLAS,从而加速Python应用程序的数值计算。
极客教程