供应商提供的 LAPACK / BLAS 库(例如 Intel 的 IPP/MKL,但还有 AMD 的 ACML,以及其他 CPU 厂商如 IBM/Power 或 Oracle/SPARC 也提供类似的库),通常针对特定的 CPU 特性高度优化,这将显著提高处理大型数据集的性能。
然而,通常情况下,你需要处理非常具体的小数据(例如 4x4 矩阵或 4D 点积,即在三维几何处理中使用的操作),对于这些情况,由于这些子程序所进行的初始测试会选择不同的代码路径,因此BLAS/LAPACK是过度的。在这种情况下,简单的 C/C++ 源代码,可能使用 SSE2...4 内嵌函数和/或编译器生成的向量化,可能会击败 BLAS/LAPACK。例如,Intel 具有两个库 - MKL 用于大型线性代数数据集,IPP 用于小型 (图形向量) 数据集。
因此,
- 你的数据集确切是什么?
- 矩阵/向量大小是多少?
- 所需的线性代数操作是什么?
另外,关于“简单的 for 循环”:给编译器一个机会来进行向量化。例如,像这样的代码:
for (i = 0; i < DIM_OF_MY_VECTOR; i += 4) {
vecmul[i] = src1[i] * src2[i];
vecmul[i+1] = src1[i+1] * src2[i+1];
vecmul[i+2] = src1[i+2] * src2[i+2];
vecmul[i+3] = src1[i+3] * src2[i+3];
}
for (i = 0; i < DIM_OF_MY_VECTOR; i += 4)
dotprod += vecmul[i] + vecmul[i+1] + vecmul[i+2] + vecmul[i+3];
可能更适合用于向量化编译器的馈送,而不是普通的。
for (i = 0; i < DIM_OF_MY_VECTOR; i++) dotprod += src1[i]*src2[i];
表达式。在某些方面,您使用for循环进行计算所表示的意思将有重大影响。
但是,如果您的向量维数足够大,则会使用BLAS版本进行计算。
dotprod = CBLAS.ddot(DIM_OF_MY_VECTOR, src1, 1, src2, 1);
将会更加简洁且可能更快。关于参考资料方面,以下内容可能会有所帮助: