我正在寻找一种解决方案,通过大量矩阵乘法来加速我的程序的性能。所以我用 MKL 替换了 CLAPACK f2c 库。不幸的是,演出的结果不是预期的。
经过调查,我遇到了一个块三角矩阵,当我尝试将它与其转置相乘时,它主要表现不佳。
为了简化问题,我用 5000 个元素的单位矩阵进行了测试(我发现了相同的结果)
姓名 | 矩阵 [尺寸,尺寸] | CLAPACK f2c(第二) | MKL_GNU_THREAD(第二个) |
---|---|---|---|
单位矩阵本身的乘法 | 5000 | 0.076536 | 1.090167 |
密集矩阵乘以其转置 | 5000*5000 | 93.71569 | 1.113872 |
- 我们可以看到单位矩阵的 CLAPACK f2c 乘法比 MKL 更快 (x14)。
- 我们可以注意到 MKL 和 CLAPACK f2c 密集矩阵乘法之间的加速度乘以 84。
此外,dense*denseT 和单位矩阵的乘法过程中的时间消耗差异非常小。
所以我试图在 CLAPACK f2c DGEMM 中找到解析矩阵乘法的优化,我发现了一个空值条件。
/* Form C := alpha*A*B + beta*C. */
i__1 = *n;
for (j = 1; j <= i__1; ++j) {
if (*beta == 0.) {
i__2 = *m;
for (i__ = 1; i__ <= i__2; ++i__) {
c__[i__ + j * c_dim1] = 0.;
/* L50: */
}
} else if (*beta != 1.) {
i__2 = *m;
for (i__ = 1; i__ <= i__2; ++i__) {
c__[i__ + j * c_dim1] = *beta * c__[i__ + j * c_dim1];
/* L60: */
}
}
i__2 = *k;
for (l = 1; l <= i__2; ++l) {
if (b[l + j * b_dim1] != 0.) { // HERE THE CONDITION
temp = *alpha * b[l + j * b_dim1];
i__3 = *m;
for (i__ = 1; i__ <= i__3; ++i__) {
c__[i__ + j * c_dim1] += temp * a[i__ + l *
a_dim1];
/* L70: */
} // ENF of condition
}
当我删除这个条件时,我得到了这样的结果:
姓名 | 矩阵 [尺寸,尺寸] | CLAPACK f2c(第二) | MKL_GNU_THREAD(第二个) |
---|---|---|---|
单位矩阵本身的乘法 | 5000 | 93.210873 | 1.090167 |
密集矩阵乘以其转置 | 5000*5000 | 93.71569 | 1.113872 |
- 在这里,我们注意到稠密和恒等式的乘法在性能方面是非常子句,现在 MKL 表现出最好的性能。
- MKL 乘法似乎比 CLAPACK f2c 更快,但只有相同数量的非空元素。
我对这个结果有两个想法:
MKL中默认不激活0优化
MKL 看不到我的稀疏矩阵中的 0 (double) 值。
你能告诉我为什么 MKL 显示性能问题吗?您有什么技巧可以绕过 dgemm 对空元素的乘法吗?
我在 CSR 中做了一个保护,它显示出更好的性能,但在这种情况下为什么 lapacke_dgemm 比 f2c_dgemmm 最差。
谢谢您的帮助 :)
MKL_VERBOSE Intel(R) MKL 2021.0 Update 1 Product build 20201104 for Intel(R) 64 架构 Intel(R) Advanced Vector Extensions 2 (Intel(R) AVX2) 启用处理器,Lnx 3.50GHz lp64 gnu_thread