我有一个矩阵,它是一个更高维度张量的表示,原则上可以是N维,但每个维度的大小相同。让我们说我想计算以下内容:
和C通过
存储为矩阵
其中有一些从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循环或单独编码每个条目。我已经尝试了不受支持的张量库,发现它比我的显式循环慢。有什么想法吗?
作为一个额外的问题,我如何有效地计算以下内容?
答案 0 :(得分:0)
编译器的优化器会为您做很多工作。一次,展开具有恒定迭代次数的循环。这可能是您的代码比库快的原因。
我建议看看通过优化产生的程序集,以便真正掌握优化的位置以及编译后程序的真实程度。
当然,您可以考虑在CPU(多线程)或GPU(cuda,OpenCL,OpenAcc等)上实现并行实现。
至于奖金问题,如果您考虑将其写为两个嵌套循环,我建议重新排列表达式,以便a_km术语在两个总和之间。不需要在内部和中执行乘法,因为它不依赖于n。虽然这可能只会给现代CPU带来轻微的性能优势......