BLAS(基础线性代数子程序库)是一个应用程序接口(API)标准,用于规范发布基础线性代数操作的数值库,如矢量或矩阵乘法。该程序集最初发布于1979年,并用于建立更大的数值程序包(如lapack)。在高性能计算领域,BLAS被广泛使用。例如,linpack的运算成绩很大程度上取决于BLAS中子程序DGEMM的表现。为提高性能,各软硬件厂商针对其产品对BLAS接口实现进行高度最佳化。BLAS的实现通常会利用特殊的浮点硬件,如向量寄存器或SIMD指令。BLAS的最新报告可以在网络库网站上找到。此外,大多数数值软件应用程序都使用BLAS兼容的库来进行线性代数计算,包括LAPACK、LINPACK、Armadillo、GNU Octave、Mathematica、MATLAB、NumPy、R和Julia。

背景

随着数值编程的出现,复杂的子例程库变得有用。这些库将包含常见高级数学运算的子例程,例如求根、矩阵求逆和求解方程组。选择的语言是Fortran。最著名的数值编程库是IBM的Scientific Subroutine Package (SSP)。这些子例程库使程序员能够专注于他们的具体问题并避免重新实现众所周知的算法。库例程也将比一般实现更好;例如,矩阵算法可能会使用完全旋转来获得更好的数值精度。库例程还将具有更高效的例程。例如,库可能包括求解上三角矩阵的程序。这些库将包括某些算法的单精度和双精度版本。

最初,这些子例程使用硬编码循环进行低级操作。例如,如果一个子程序需要执行矩阵乘法,则该子程序将具有三个嵌套循环。线性代数程序有许多常见的低级运算(所谓的“内核”运算,与操作系统无关)。1973 年至 1977 年间,确定了其中一些内核操作。这些内核操作成为数学库可以调用的已定义子例程。内核调用比硬编码循环具有优势:库例程更具可读性,出现错误的机会更少,并且可以优化内核实现的速度。这些使用标量向量的内核运算的规范,即 1 级基本线性代数子例程 (BLAS),于 1979 年发布。BLAS 用于实现线性代数子例程库LINPACK。

BLAS 抽象允许定制以获得高性能。例如,linpack 是一个通用库,无需修改即可在许多不同的机器上使用。LINPACK 可以使用 BLAS 的通用版本。为了获得性能,不同的机器可能会使用定制版本的 BLAS。随着计算机体系结构变得更加复杂,向量机出现了。向量机的 BLAS 可以使用机器的快速向量运算。(虽然矢量处理器最终失宠,但现代 CPU 中的矢量指令对于 BLAS 例程的最佳性能至关重要。)

其他机器功能也变得可用并且也可以被利用。因此,从 1984 年到 1986 年,BLAS 通过涉及向量矩阵运算的 2 级内核运算得到了增强。内存层次结构也被认为是可以利用的东西。许多计算机都有比主存快得多的高速缓存;保持矩阵操作本地化可以更好地利用缓存。1987 年和 1988 年,3 级 BLAS 被确定用于执行矩阵矩阵运算。3 级 BLAS 鼓励块分区算法。lapack库使用 3 级 BLAS。

最初的 BLAS 仅涉及密集存储的向量和矩阵。BLAS 的进一步扩展(例如稀疏矩阵)已经得到解决。

更新内容

BLAS的接口由BLAS技术(BLAST)论坛标准化,提供了C(“CBLAS接口”)和Fortran(“BLAS接口”)的绑定,确保了其广泛的适用性和易用性。BLAS的参考实现属于公共领域,虽然它并没有针对速度进行优化,但它为其他优化实现提供了基准。针对不同硬件平台的优化实现,如cuBLAS(英伟达 GPU)、rocBLAS(AMD GPU)和OpenBLAS,使得BLAS能够在异构计算架构中实现高效的线性代数运算。此外,BLIS(类似BLAS的库实例化软件)、Arm性能库、asp.net ajax英特尔数学核心库(iMKL)等基于CPU的BLAS库分支也为性能提升做出了贡献。AMD针对其平台优化了BLIS分支,而ATLAS是一个可以自动优化以适应任意架构的便携式库。iMKL是专门针对x86和x86-64架构优化的库,而OpenBLAS是一个开源库,为多种流行架构提供了手动优化。linpack基准测试,一个重要的性能测量工具,严重依赖于BLAS例程gemm。这些优化实现的存在,使得BLAS不仅在功能上兼容,而且在性能上也能满足不同计算需求。

参考资料