问题描述
我正在寻找一种解决方案,通过大量矩阵乘法来加速我的程序的性能。所以我用 MKL 替换了 clapACK f2c 库。遗憾的是,演出结果并不如预期。
经过调查,我遇到了一个块三角矩阵,当我尝试将其与其转置相乘时,该矩阵的性能很差。
为了简化问题,我使用 5000 个元素的单位矩阵进行了测试(我发现了相同的说法)
NAME | 矩阵[大小,大小] | clapACK f2c(second) | MKL_GNU_THREAD(第二个) |
---|---|---|---|
单位矩阵自身的乘法 | 5000 | 0.076536 | 1.090167 |
稠密矩阵乘以其转置 | 5000*5000 | 93.71569 | 1.113872 |
此外,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
}
当我删除这个条件时,我得到了这样的结果:
NAME | 矩阵[大小,大小] | clapACK f2c(第二个) | MKL_GNU_THREAD(第二个) |
---|---|---|---|
单位矩阵自身的乘法 | 5000 | 93.210873 | 1.090167 |
稠密矩阵乘以其转置 | 5000*5000 | 93.71569 | 1.113872 |
我对这个结果有两个想法:
-
MKL 中默认不激活 0 优化
-
MKL 看不到稀疏矩阵中的 0(双)值。
你能告诉我为什么 MKL 会显示性能问题吗? 你有什么技巧可以用 dgemm 绕过空元素的乘法吗?
我在 CSR 中做了一个保护,它显示了更好的性能,但为什么 lapacke_dgemm 比 f2c_dgemmm 最差。
感谢您的帮助:)
MKL_VERBOSE Intel(R) MKL 2021.0 Update 1 Product build 20201104 for Intel(R) 64 Architecture Intel(R) Advanced Vector Extensions 2 (Intel(R) AVX2) 启用处理器,Lnx 3.50GHz lp64 gnu_thread
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)