令我惊讶的是,我无法在web上跟踪基于cilkplus'数组符号的BLAS的任何实现。这很奇怪,因为cilkplus应该在今天的多核工作站cpu上确保(超过)体面的性能,再加上非常富有表现力和紧凑的BLAS算法表示。更奇怪的是,考虑到BLAS/LAPACK是密集矩阵计算的事实上的标准(至少,作为规范)。
我知道有其他更最新和更复杂的库试图改进/扩展blas/lapack,例如,我已经看过了eigen和flens,但如果有一个"标准"blas实现的cilkplus版本,那就太好了。
这取决于cilkplus的有限传播吗?
http://parallelbook.com/downloads有Cilk Plus代码(参见" code EXAMPLES FROM BOOK"),用于Cholesky分解示例中的一些BLAS操作:gem、portrf、syk和trsm。这些例程是模板,因此它们适用于任何精度。
从好的方面来说,Cilk plus版本给了你很好的组合属性,即你可以在刷出树的不同部分使用它们而不用担心。消极的一面是,如果你不需要干净的组合,那么很难与高度调优的并行BLAS库竞争,因为Cilk Plus算法往往是缓存无关的,而高度调优的库可以利用缓存感知。例如,缓存感知算法可以仔细地安排同一核心上的多个线程在相同的块上工作,从而节省内存获取开销。为每台机器获得正确的缓存感知需要做很多工作,但是BLAS作者愿意做这项工作。正是缓存感知("我拥有整台机器"编程)阻碍了干净的组合,所以你不能两者兼得。
对于一些BLAS操作,与非结构化并行性相比,Cilk Plus的fork-join结构似乎也限制了性能。
以gemm为例,在最后,并行例程只是调用blas例程(gemm, gemm等)。这可能是netlib参考,或atlas,或openblas,或mkl,但这在建议的引用中是不透明的。我要求存在引用例程的cilkplus实现,例如像
这样的东西void dgemm(MATRIX & A, MATRIX & B, MATRIX & C) {
#pragma cilk grainsize = 64
cilk_for(int i = 1; i <= A.rows; i++) {
double *x = &A(i, 1);
for (int j = 1; j <= A.cols; j++, x += A.colstride)
ROW(C, i) += (*x) * ROW(B, j);
}
}