Мне нужно сделать два умножения матрицы матрицы, чтобы оценить некоторые промежуточные звенья:
Я могу сделать это, используя несколько вариантов 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:
а) '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 )
б) «Т», «Н» + «Т», «Н»
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 )
в) 'N', 'N' + 'T', 'N' (см. Выше)
Не знаю почему, но комбинация в) самая быстрая. Это не имеет смысла для меня. В комбинации а) и б) я использую предварительно преобразованные матрицы B (Bt), и начальный размер E, конечно, отличается.
Мне не кажется логичным, почему c) должен быть самым быстрым, потому что 'N','N'
быстрее, чем 'T','N'
, или наоборот. В любом случае, а) или б) должны быть самыми быстрыми.
Так что у меня есть пара возможностей:
Либо компилятор (ifort 19) замечает две dgemms друг за другом и каким-то волшебным образом объединяет их, либо поскольку размеры настолько сильно различаются, что имеет огромное значение. В последнем случае я бы все же предположил, что комбинация b) будет самой быстрой, потому что pqdim (наибольшее измерение) является ведущим измерением для обеих матриц ...
А может я просто что-то упустил?