This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: int vs. float divide optimization on AXP EV45


On Thu, Nov 19, 1998 at 11:55:43AM -0800, B. James Phillippe wrote:
> 	I ran an expirament to test this statement with egcs-2.91.56 (and
> the optimizer off), and sure enough, he is correct.  I see a noticeable
> performance advantage on my EV45 (21064A) box when using a double for
> division over an int.  However, and here is where my question lies, when I
> turn the optimizer on, the integer divide becomes much faster than the
> floating divide.

Without any details on how you are testing things, it is hard to say. 

In general, without knowing ranges of inputs, a 32-bit divide may be
converted only to a 53-bit double-precision divide.

The worst case cycle time for double precision divide on EV4 is 63
cycles.  Plus some surrounding code (conversions, loads and stores)
takes us up to about 83 cycles before you can do anything useful with
the result.

The 32-bit integer division routines on Linux are fairly efficient.
I clock them at 65 to 72 cycles on average.  

So by my measurements, we'd only win doing the division in FP if we
have something else we can be doing in parallel in the integer units.
And that sort of resource-dependant pattern selection GCC simply does
not know how to do.


r~
main()
{
  unsigned int sum_i, sum_f, start, stop;
  int a, b, d1, d2, i;

  sum_i = sum_f = 0;
  for (i = 0; i < 100; i++)
    {
      a = random();
      b = random();
      
      asm volatile ("rpcc %0" : "=r"(start), "=r"(a), "=r"(b) : "1"(a), "2"(b));
      d1 = a / b;
      asm volatile ("addl %1,0,%1\n\trpcc %0" : "=r"(stop) : "r"(d1));
      sum_i += stop - start;

      asm volatile ("rpcc %0" : "=r"(start), "=r"(a), "=r"(b) : "1"(a), "2"(b));
      d2 = (double)a / (double)b;
      asm volatile ("addl %1,0,%1\n\trpcc %0" : "=r"(stop) : "r"(d2));
      sum_f += stop - start;

      if (d1 != d2)
	printf("differ: %d / %d => %d vs %d\n", a, b, d1, d2);
    }
  printf("sums: %d int, %d fp\n", sum_i, sum_f);
  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]