高效的张量乘法

时间:2018-05-04 15:15:11

标签: c++ eigen tensor

我有一个矩阵,它是一个更高维度张量的表示,原则上可以是N维,但每个维度的大小相同。让我们说我想计算以下内容:

eqn1

和C通过

存储为矩阵

eqn2

其中有一些从ij到I和kl到J的映射。

我可以使用嵌套for循环执行此操作,其中我的张量的每个维度的大小为3,通过

for (int i=0; i<3; i++){
    for (int j=0; j<3; j++){
        I = map_ij_to_I(i,j);
        for (int k=0; k<3; k++){
            for (int l=0; l<3; l++){
                J = map_kl_to_J(k,l);
                D(I,J) = 0.;
                for (int m=0; m<3; m++){
                    for (int n=0; n<3; n++){
                        M = map_mn_to_M(m,n);
                        D(I,J) += a(i,m)*C(M,J)*b(j,n);
                    }
                }
            }
        }
    }
}

但这非常混乱而且效率不高。我正在使用Eigen矩阵库,所以我怀疑有一个更好的方法来做这个比for循环或单独编码每个条目。我已经尝试了不受支持的张量库,发现它比我的显式循环慢。有什么想法吗?

作为一个额外的问题,我如何有效地计算以下内容?

eqn3

1 个答案:

答案 0 :(得分:0)

编译器的优化器会为您做很多工作。一次,展开具有恒定迭代次数的循环。这可能是您的代码比库快的原因。

我建议看看通过优化产生的程序集,以便真正掌握优化的位置以及编译后程序的真实程度。

当然,您可以考虑在CPU(多线程)或GPU(cuda,OpenCL,OpenAcc等)上实现并行实现。

至于奖金问题,如果您考虑将其写为两个嵌套循环,我建议重新排列表达式,以便a_km术语在两个总和之间。不需要在内部和中执行乘法,因为它不依赖于n。虽然这可能只会给现代CPU带来轻微的性能优势......