From: jacobsd@cs.orst.edu (Dana Jacobsen)
Subject: Re: solution to "-O2" slower than "-O -g"
Organization: Oregon State University, Computer Science Dept
Distribution: gnu
Date: Mon, 6 Apr 1992 05:18:27 GMT

  I have found that gcc 2.x sometimes makes code slower with the 
"strength-reduce" option.  Since "-O2" implies "-fstrength-reduce",
some code is slower with "-O2" than "-O".  The combinations of
"-O2 -fno-strength-reduce" or "-O -fschedule-insns2" often produce 
very good code.
  My gelim program (results and program below) shows this quite 
drastically.  gcc 1.40 doesn't suffer from this -- strength-reduce
actually improves the code (though neither is as fast as gcc 2.x
with or without it).  In some other benchmarks (Byte's arith.c
(a truly lame benchmark), dhrystone 2.0, and flops.c 1.2), 
the strength-reduce optimization seems to have no effect whatsoever.

An aside:  gcc 2.1 actually did beat Sun's unbundled C compiler on
the dhrystone 2.0 -- 50505 d/s for gcc 2.1 vs. 48879 d/s for SC1.0/cc.
Previously, gcc 2.0 got 34816 d/s, gcc 1.40 for 39215 d/s, and Sun's 
bundled C compiler for 32258 d/s.  Quite an improvement guys!
  However, gcc is still slower than SC1.0 on my gelim program.  The
results with all optimizations off are _very_ poor.




Performed on a Sparc 2 (4/75) with 64 Meg of RAM
All MFLOPS ratings are given by gelim 1.3, 1000x1000 matrix

GNU time -v gives the following memory results:
	Shared Text size (kbytes): 0
	Unshared Data size (kbytes): 14850
	Stack size (kbytes): 0
	Average size (kbytes): 14850
	Maximum resident set size (kbytes): 7932
	Integral resident set size (kbytes): 14850


compiler   optimization options                         ``MFLOPS''
---------- -------------------------------------------- -------------
gcc 2.1                                                 0.29027
gcc 2.1    -O                                           2.37719
gcc 2.1    -O2                                          2.14247
gcc 2.1    -O -fschedule-insns2 -frerun-cse-after-loop  2.52384
gcc 2.1    -O2 -fno-strength-reduce                     2.52511

gcc 2.0    -O                                           2.38641
gcc 2.0    -O2                                          1.21537
gcc 2.0    -O2 -fno-strength-reduce                     2.39427

gcc 1.40                                                1.28253
gcc 1.40   -O                                           1.88440
gcc 1.40   -O -fstrength-reduce                         1.90306

SC1.0/cc                                                1.30068
SC1.0/cc   -O                                           2.36579
SC1.0/cc   -O4                                          2.49984
SC1.0/cc   -fast -O4                                    2.86749

cc                                                      1.29462
cc         -O4                                          2.38030


/*   
 *  gelim v1.3  -- Dana Jacobsen 
 *  21 Feb 92      jacobsd@cs.orst.edu
 */

#include <sys/param.h>
#include <sys/times.h>

#ifndef MAT
#define MAT 1000
#endif

#ifndef HZ
#define HZ 60
#endif

static void hilbert(a, n)
double	a[MAT][MAT];
register int	n;
{
  register int	i,
		j;

  for (i = 0;  i < n;  i++)
    for (j = 0;  j < n;  j++)
      a[i][j] = (double) n / (double) (i + j + 1);
}

static void gelim(a, n)
double	a[MAT][MAT];
register int	n;
{
  register double	m;
  register int		i,
  			j,
  			k;

  for (j = 0;  j < (n - 1);  j++)
    for (i = j + 1;  i < n;  i++) {
      m = a[i][j] / a[j][j];
      a[i][j] = 0;
      for (k = j + 1;  k < n;  k++) {
        a[i][k] -= m * a[j][k];
      }
    }
}

static long matcount(n)
int	n;
{
  long		fcount;
  double	ftemp;

  fcount = 0;
  ftemp = n * n * n;
  ftemp *= 2; ftemp /= 3;
  fcount += ftemp;
  ftemp = n * n;
  ftemp /= 2;
  fcount -= ftemp;
  ftemp = n;
  ftemp /= 6;
  fcount -= ftemp;

  return(fcount);
}

static double mattime(n, answer)
int	n;
double	answer;
{

  double	m[MAT][MAT];
  double	sum = 0;
  double	mflops;
  int	i;
  long	flopcount,
  	starttime,
  	totaltime;
  struct tms timeval;

  totaltime = 0;

  hilbert(m, n);

  times(&timeval);
  starttime = timeval.tms_utime;
  gelim(m, n);
  times(&timeval);
  totaltime = timeval.tms_utime - starttime;

  flopcount = matcount(n);

  for (i=0; i<MAT; i++)
    sum += m[5][i];

  printf(" matrix size: %4d, flopcount = %9ld, sum = %3.9lf \n", 
         n, flopcount, sum);

  sum -= answer;
  if (sum < 0) sum *= -1;
  if (sum > 0.00000001)
    printf("\n ********** Sum should be %3.9lf **********\n\n", answer);

  printf(" time for LU factorization:  %6.2f seconds ", totaltime / 60.0);
  mflops = ((float) HZ * flopcount ) / (1000000.0 * totaltime );
  printf("  :::::::    MFLOPS: %5.5f \n", mflops);
  return(mflops);
}

static void mflopcalc(mflops, n, answer)
double	*mflops;
int	n;
double	answer;
{
  double	timetaken,
  	secs;
  long	mins;

  if (*mflops) {
    timetaken = ( matcount(n) / 1000000.0 ) / *mflops;
    mins      = (int) timetaken / 60;
    secs      = timetaken - (double) (mins * 60);

    printf("\nEstimated time for %4d x %4d matrix: %d min %2.2lf sec \n\n", 
           n, n, mins, secs);
  }

  *mflops = mattime(n, answer);

}

int main() {

  double	mflops = 0;

                 mflopcalc(&mflops, 50,   0.089101838);
  if (MAT >  99) mflopcalc(&mflops, 100,  0.356499180);
  if (MAT > 199) mflopcalc(&mflops, 200,  1.155221833);
  if (MAT > 499) mflopcalc(&mflops, 500,  4.534148440);
  if (MAT > 999) mflopcalc(&mflops, 1000,11.700658579);

  return(0);
}
-- 
Dana Jacobsen                       Oregon State University
jacobsd@cs.orst.edu                   Computer Science
..!hplabs!hp-pcd!orstcs!jacobsd
Dana_Jacobsen@RPITSMTS.BITNET           Power, Corruption, & Lies -- Bush '92
-- 
Dana Jacobsen                       Oregon State University
jacobsd@cs.orst.edu                   Computer Science
..!hplabs!hp-pcd!orstcs!jacobsd
Dana_Jacobsen@RPITSMTS.BITNET           Power, Corruption, & Lies -- Bush '92


Newsgroups: gnu.gcc.bug