[patch, fortran, RFC] Inline matmul(transpose(a),b)
Thomas Koenig
tkoenig@netcologne.de
Mon May 15 22:14:00 GMT 2017
Hello world,
the attached patch, just an RFC so far, implements inlining
for matmul(transpose(a),b).
This implements
c = 0
do i=1, size(a,2)
do j=1, size(b,2)
do k=1, size(a,1)
c(i,j) = c(i,j) + a(k,i) * b(k,j)
end do
end do
end do
which is at least capable of being vectorized with recent trunk
and which shows an improvement over the library version:
$ cat bench0.f90
program main
implicit none
integer, parameter :: n = 30, m=40, cnt=20
real(kind=8), dimension(cnt,n) :: a
real(kind=8), dimension(cnt,m) :: b
real(kind=8), dimension(n,m) :: c
integer :: i, j, k
real(kind=8) :: s
integer :: rep = 100000
integer :: irep
integer, parameter :: nmin = min(n, m, cnt)
call random_number(a)
call random_number(b)
s = 0.
do irep=1,rep
do i=1,nmin
a(i,i) = (a(i,i) + 1.)*0.5 ! Just to confuse the optimizer
end do
c = matmul(transpose(a),b)
s = s + sum(c)
end do
print *,s
end program main
$ gfortran -Ofast -finline-matmul-limit=0 bench0.f90 && time ./a.out
622153335.54627311
real 0m2,896s
user 0m2,888s
sys 0m0,008s
$ gfortran -Ofast bench0.f90 && time ./a.out
642240828.34605432
real 0m1,378s
user 0m1,376s
sys 0m0,000s
So, is this the right way to go, or should I try some other version of
ordering the DO loops? I seem to remember that we talked about
using some kind of vector temporary, but I am not sure how this was
done, or if it would bring large improvements for really small matrix
sizes.
Regards
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p1.diff
Type: text/x-patch
Size: 5247 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20170515/6e6ea2c3/attachment.bin>
More information about the Fortran
mailing list