[patch, fortran] Create temporary variables for matmul
Thomas Koenig
tkoenig@netcologne.de
Mon May 8 18:19:00 GMT 2017
Hi Jerry,
> OK. Could you post some before and after performance results. Intuitively this
> makes sense to do, but empirically does it pay off.
Thanks for the reviews!
Here is a quick&dirty benchmark, with the patch, with
-finline-matmul-limit=0 used to inhibit matmul inlining
(to simulate the behavior without).
$ cat bench.f90
program main
implicit none
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: n1 = 10000
integer, parameter :: n2 = 1000
integer :: i,j,ind
real(dp), dimension(3,3*n2) :: a, b
real(dp), dimension(3,3) :: c
real(dp) :: s
s = 0
do i=1,n1
call random_number(a)
call random_number(b)
do j=1,n2
ind = 3*j-2
s = s + sum(matmul(a(:,ind:ind+2),b(:,ind:ind+2)))
end do
end do
print *,s
end program main
$ gfortran -Ofast -finline-matmul-limit=0 bench.f90 && time ./a.out
67501526.340284660
real 0m4,856s
user 0m4,852s
sys 0m0,000s
$ gfortran -Ofast bench.f90 && time ./a.out
67502996.159002081
real 0m2,583s
user 0m2,580s
sys 0m0,000s
Also interesting, a version which actually uses allocatable variables
as temporaries because we don't to value propagation in the front end:
program main
implicit none
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: n1 = 10000
integer, parameter :: n2 = 1000
integer :: i,j,ind, ind2
real(dp), dimension(3,3*n2) :: a, b
real(dp), dimension(3,3) :: c
real(dp) :: s
s = 0
do i=1,n1
call random_number(a)
call random_number(b)
do j=1,n2
ind = 3*j-2
ind2 = ind + 2
s = s + sum(matmul(a(:,ind:ind2),b(:,ind:ind2)))
end do
end do
print *,s
end program main
$ gfortran -Ofast -finline-matmul-limit=0 bench2.f90 && time ./a.out
67500364.375209823
real 0m5,480s
user 0m5,472s
sys 0m0,000s
$ gfortran -Ofast bench2.f90 && time ./a.out
67498343.869140804
real 0m3,475s
user 0m3,476s
sys 0m0,000s
Regards
Thomas
More information about the Fortran
mailing list