代码之家  ›  专栏  ›  技术社区  ›  NateM

有效张量乘法

  •  2
  • NateM  · 技术社区  · 8 年前

    我有一个矩阵,它是一个高维张量的表示,原则上可以是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);
                        }
                    }
                }
            }
        }
    }
    

    但这相当混乱,效率也不高。我使用的是特征矩阵库,所以我想可能有比for循环或单独编码每个条目更好的方法来实现这一点。我尝试了不受支持的张量库,发现它比显式循环慢。有什么想法吗?

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

    eqn3

    1 回复  |  直到 8 年前
        1
  •  0
  •   Sergio Monteleone    8 年前

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

    我建议看一下优化后生成的程序集,以真正了解可以在哪里进行优化,以及程序编译后的真实外观。

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

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