Какой вызов dgemm самый быстрый? - PullRequest
1 голос
/ 16 мая 2019

Мне нужно сделать два умножения матрицы матрицы, чтобы оценить некоторые промежуточные звенья:

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:

а) '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 (наибольшее измерение) является ведущим измерением для обеих матриц ...

А может я просто что-то упустил?

...