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