BLAS 与 LAPACK
BLAS 和 LAPACK 是数值线性代数的基石库——几乎每一个科学计算工具,从 NumPy、MATLAB 到深度学习框架,底层都调用的那些高度优化的代码。BLAS 提供底层构件(向量与矩阵运算);LAPACK 在其上构建高层求解器(线性系统、最小二乘、特征值、SVD)。两者合在一起,正是快速、正确的线性代数成为一次库调用而非一个研究课题的原因。
BLAS 按算术与数据搬运的关系分为三级。第一级是向量-向量(如点积和 saxpy),对 O(n) 数据做 O(n) 工作。第二级是矩阵-向量,对 O(n^2) 数据做 O(n^2) 工作。第三级是矩阵-矩阵,对仅 O(n^2) 的数据做 O(n^3) 算术——而这个不平衡正是秘诀。第三级把每个载入的数据元素多次重用,故能接近机器的峰值速度运行;其余两级则被内存带宽饿着。
这正是现代算法分块的原因:它们被改写为尽可能多地耗在第三级矩阵-矩阵核上,把矩阵划分为能放进缓存的瓦片并逐瓦片运算。LAPACK 的分解全都分块,正是为了让其 O(n^3) flop 的大头落在调校良好的第三级 BLAS 里,达到峰值性能的一大部分,而不被内存流量扼住。
实用的智慧很直白:别自己写。厂商调校的 BLAS 实现(OpenBLAS、Intel MKL、Apple Accelerate)和 LAPACK 里的算法,凝结了数十年在数值稳定性、缓存分块和并行性上的工作,是一个手写的三重循环无法企及的——速度上往往差一到两个数量级,且准确性保证好得多。去用库吧。
第三级 BLAS 对二次的数据做三次的算术,故大量重用缓存数据并接近峰值速度运行——这是分块算法的基础。
BLAS 是一套接口(一份规范),而非单个程序。许多实现都遵循它——参考 BLAS、OpenBLAS、MKL、BLIS——它们在计算相同结果的同时,速度可相差几个数量级,这正是你链接哪个 BLAS 可能影响巨大的原因。