哪个dgemm通话最快?

时间:2019-05-16 10:20:42

标签: fortran lapack blas

我需要做两个矩阵矩阵乘法来评估一些中间体:

enter image description here

我可以使用dgemms的多个变体来做到这一点。到目前为止,我拥有的集合使用一个'N','N'乘法和一个'T','N'(N表示正常,T表示变换):

       call dgemm('N','N',Pdim,Kdim,pqdim,           &
                 & 1.0d0,B,Pdim,D(1,1,iamthr),pqdim, &
                 & 0.0d0,Etilde(1,1,iamthr),Pdim     )

        call dgemm('T','N',pqdim,Kdim,Pdim,              &
                 & 1.0d0,B,Pdim,Etilde(1,1,iamthr),Pdim, &
                 & 0.0d0,E(1,1,iamthr),pqdim             )

其中Pdim是P的维,Kdim是K的维,pqdim是pq和ij的维。 “ Kdim”是最小的尺寸,“ Pdim”的尺寸从几百到2000,而pqdim的尺寸范围从1000到100000。

现在,我尝试了3种版本的dgemm调用:

a)'N','N'+'N','N'

    call dgemm('N','N',Pdim,Kdim,pqdim,          &
             & 1.0d0,B,Pdim,D(1,1,iamthr),pqdim, &
             & 0.0d0,Etilde(1,1,iamthr),Pdim     )

    call dgemm('N','N',pqdim,Kdim,Pdim,                 &
             & 0.50d0,Bt,pqdim,Etilde(1,1,iamthr),Pdim, &
             & 0.0d0,E(1,1,iamthr),pqdim                )

b)'T','N'+'T','N'

    call dgemm('T','N',Pdim,Kdim,pqdim,            &
             & 1.0d0,Bt,pqdim,D(1,1,iamthr),pqdim, &
             & 0.0d0,Etilde(1,1,iamthr),Pdim       )

    call dgemm('T','N',Kdim,pqdim,Kdim,              &
             & 1.0d0,Etilde(1,1,iamthr),Pdim,B,Pdim, &
             & 0.0d0,E(1,1,iamthr),Kdim              )

c)'N','N'+'T','N'(请参见上文)

我不知道为什么,但是组合c)是最快的。这对我来说没有意义。在组合a)和b)中,我使用了预变换矩阵B(Bt),E的前导维当然是不同的。

对于我来说,为什么c)应该是最快的似乎并不合逻辑,因为'N','N''T','N'更快,反之亦然。无论哪种方式,a)或b)都必须最快。

所以我有两种可能性:

要么编译器(ifort 19)注意到两个dgemm,然后以某种方式神奇地将它们连接在一起,要么是因为尺寸如此之大,以至于产生了巨大的差异。在后一种情况下,我仍然会认为组合b)最快,因为pqdim(最大维度)是两个矩阵的前导维度...

或者也许我只是错过了一些必不可少的东西?

0 个答案:

没有答案