f771 assertion failure
Toon Moene
toon@moene.indiv.nluug.nl
Mon Sep 29 13:54:00 GMT 1997
This weekend, Richard Henderson wrote:
> This while compiling apsi.f from spec95's 145.fpppp [ on Alpha ].
I have let this slip for now, because fixing the bugs is more
important than getting any speed out of egcs-compiled binaries, but
there is an issue that should not be forgotten when trying to run
benchmark programs (especially Fortran ones, such as the SPECfp95
codes):
Until the non-reduction-of-SUBREG-GIVs problem is solved, there is
no point in running benchmark codes compiled by g77/egcs on an
Alpha.
Let me throw in some facts I have been able to discover thanks to
being granted access to an Alpha since last week (thanks Greg!):
Consider the following routine:
subroutine daxpy(n,da,dx,dy)
double precision dx(n),dy(n),da
integer i,n
do i = 1, n
dy(i) = dy(i) + da*dx(i)
enddo
end
>From first principles, one would expect the compiler to generate
two loads, one float multiply, one float add, one store and two
address increments (by 8 in this case) in the loop body. Because
the strength reduction pass doesn't recognise the general induction
variables ADDR-of-d{x|y} + i*8 - 8, this optimisation is not done
and the resulting code is about 25 - 30 % slower than necessary.
Code compiled with f2c + egcs (optimal) gets about this speed-up.
The reason is that rank-1 arrays that are 0-based do lead to
recognisable GIVs.
In the Real World, however, things are far worse. As soon as you
leave the flat, rank-1 world of C, and look at some Real World Code:
subroutine resid(res,u,rhs,n)
implicit none
integer n
double precision res(n,n),rhs(n,n),u(n,n)
integer i,j
double precision h, h2i
h=1.d0/(n-1)
h2i=1.d0/(h*h)
do j = 2, n-1
do i = 2, n-1
res(i,j)=-h2i*(u(i+1,j)+u(i-1,j)+u(i,j+1)+u(i,j-1)-
, 4.d0*u(i,j))+rhs(i,j)
enddo
enddo
end
things aren't that easy anymore. There still is a difference
compiling this code with f2c + egcs, g77 with 0-based arrays and g77
with the original code, but it is small:
Inner Loop f2c + egcs g77/0-based g77/1-based
integer multiplies 2 2 6
integer adds / subs 11 16 21
integer s8add's 7 2 6
integer shifts / bis - 2 7
float multiplies 2 2 2
float adds / subs / negs 5 5 5
loads 6 6 6
stores 1 1 1
BTW, the optimal sequence would be (which would be generated on my
m68k if it had enough address registers):
integer multiplies -
integer adds / subs 8
integer s8add's -
integer shifts / bis -
float multiplies 2
float adds / subs / negs 6
loads 6
stores 1
The difference between the f2c + egcs and the g77/egcs (for 1-based
arrays) generated code can already run close to a factor of 2 (a
rank-3 example program I have lying around did 10.2 seconds for the
g77/egcs compiled executable and 5.5 seconds for the f2c + egcs
one). Clearly, once this problem is beaten, we have a g77 that can
be faster by up to a factor of 3 or 4 on some Fortran codes.
Concluding: Until this problem is solved, there's little reason to
run Fortran based benchmark code compiled by g77/egcs on Alpha's.
HTH,
Toon.
PS: The apsi benchmark from SPEC is, if we may believe the Web page
description, a sort of air pollution distribution model, that -
qualitate qua - has to include quite a lot of meteorology. I expect
it therefore to be like our own limited area weather forecasting
code.
More information about the Gcc
mailing list