我需要做两个矩阵矩阵乘法来评估一些中间体:
我可以使用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(最大维度)是两个矩阵的前导维度...
或者也许我只是错过了一些必不可少的东西?