Re: [cp-patches] Float/Double compare

2007-10-12 Thread Andrew John Hughes
On Tuesday 03 July 2007 23:16:19 Ian Rogers wrote:
> Here's a revised version of the patch following suggestions from Andrew
> Haley.
>
> Ian

Committed:

2007-10-12  Ian Rogers  <[EMAIL PROTECTED]>
2007-10-12  Andrew Haley  <[EMAIL PROTECTED]>

PR classpath/33741:
* java/lang/Double.java:
(compare(double,double)): Increase performance
of this method.
* java/lang/Float.java:
(compare(float,float)): Likewise.



-- 
Andrew :)




Re: [cp-patches] Float/Double compare

2007-07-03 Thread Ian Rogers
Here's a revised version of the patch following suggestions from Andrew 
Haley.


Ian
--- java/lang/Float.java2006-12-10 15:25:44.0 -0500
+++ java/lang/Float.java2007-07-02 12:17:29.0 -0400
@@ -596,16 +596,25 @@
*/
   public static int compare(float x, float y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinities and try again
-if (x == 0 && y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
+  // handle the easy cases:
+  if (x < y)
+ return -1;
+  if (x > y)
+ return 1;
 
-return x > y ? 1 : -1;
+  // handle equality respecting that 0.0 != -0.0 (hence not using x == y):
+  int ix = floatToRawIntBits(x);
+  int iy = floatToRawIntBits(y);
+  if (ix == iy)
+ return 0;
+
+  // handle NaNs:
+  if (x != x)
+ return (y != y) ? 0 : 1;
+  else if (y != y)
+ return -1;
+
+  // handle +/- 0.0
+  return (ix < iy) ? -1 : 1;
   }
 }
--- java/lang/Double.java   2006-12-10 15:25:44.0 -0500
+++ java/lang/Double.java   2007-07-02 12:18:36.0 -0400
@@ -587,16 +587,25 @@
*/
   public static int compare(double x, double y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinites and try again
-if (x == 0 && y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
+  // handle the easy cases:
+  if (x < y)
+ return -1;
+  if (x > y)
+ return 1;
 
-return x > y ? 1 : -1;
+  // handle equality respecting that 0.0 != -0.0 (hence not using x == y):
+  long lx = doubleToRawLongBits(x);
+  long ly = doubleToRawLongBits(y);
+  if (lx == ly)
+ return 0;
+
+  // handle NaNs:
+  if (x != x)
+ return (y != y) ? 0 : 1;
+  else if (y != y)
+ return -1;
+
+  // handle +/- 0.0
+  return (lx < ly) ? -1 : 1;
   }
 }


Re: [cp-patches] Float/Double compare

2007-07-01 Thread Andrew Pinski

On 6/30/07, Ian Rogers <[EMAIL PROTECTED]> wrote:

Attached is a patch that improves the performance of an Float/Double
compare by exploiting information carried in their bit integer/long
versions sign bit. It removes one comparison from the normal path, as
well as making other compares with ints/longs. When sorting an array of
floats this can yield a little under a 8% speed up on a Pentium 4.
There's a thread discussing whether this is a good or bad idea on the
main mailing list, but so far I'm merrily talking to myself :-)


This is going to slow down this function for PowerPC (except for
Power6+) where you have to take a huge hit to transfer between
register sets via the stack.  For an example on the Cell, this is
going to be an extra 40-100 cycle hit.

-- Pinski



Re: [cp-patches] Float/Double compare

2007-06-30 Thread Ian Rogers

Andrew Pinski wrote:

On 6/30/07, Ian Rogers <[EMAIL PROTECTED]> wrote:

Attached is a patch that improves the performance of an Float/Double
compare by exploiting information carried in their bit integer/long
versions sign bit. It removes one comparison from the normal path, as
well as making other compares with ints/longs. When sorting an array of
floats this can yield a little under a 8% speed up on a Pentium 4.
There's a thread discussing whether this is a good or bad idea on the
main mailing list, but so far I'm merrily talking to myself :-)


This is going to slow down this function for PowerPC (except for
Power6+) where you have to take a huge hit to transfer between
register sets via the stack.  For an example on the Cell, this is
going to be an extra 40-100 cycle hit.
I guess there are a lot of factors to do with the underlying 
architecture. My feeling is that we should move the code to 
VMFloat/VMDouble and then the VM can choose the appropriate version. 
Having the regular version optimized for Intel would make sense to me. 
Its not straight forward for me to benchmark the code on non-IA32 
architectures, in particular Cell. I'll try to do a Jikes RVM benchmark 
on a PowerPC I have access to in the week. My feeling is that the 
performance may not be as bad as you imagine, but it's hard to predict - 
and this may not be an architecture you care about anyway.


Regards,
Ian



[cp-patches] Float/Double compare

2007-06-30 Thread Ian Rogers
Attached is a patch that improves the performance of an Float/Double 
compare by exploiting information carried in their bit integer/long 
versions sign bit. It removes one comparison from the normal path, as 
well as making other compares with ints/longs. When sorting an array of 
floats this can yield a little under a 8% speed up on a Pentium 4. 
There's a thread discussing whether this is a good or bad idea on the 
main mailing list, but so far I'm merrily talking to myself :-)


Ian
--- java/lang/Double.java   2006-12-10 20:25:44.0 +
+++ java/lang/Double.java   2007-06-30 22:21:39.98610 +0100
@@ -587,16 +587,17 @@
*/
   public static int compare(double x, double y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinites and try again
-if (x == 0 && y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
-
-return x > y ? 1 : -1;
+long lx = doubleToLongBits(x);
+long ly = doubleToLongBits(y);
+if (lx == ly) return 0;
+if (isNaN(x)) return 1;
+if (isNaN(y)) return -1;
+int lx_sign = (int)(lx>>63);
+int ly_sign = (int)(ly>>63);
+if (lx_sign == ly_sign) {
+  return x > y ? 1 : -1;
+} else {
+  return lx_sign - ly_sign;
+}
   }
 }
--- java/lang/Float.java2006-12-10 20:25:44.0 +
+++ java/lang/Float.java2007-06-30 22:10:46.099648000 +0100
@@ -596,16 +596,17 @@
*/
   public static int compare(float x, float y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinities and try again
-if (x == 0 && y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
-
-return x > y ? 1 : -1;
+int ix = floatToIntBits(x);
+int iy = floatToIntBits(y);
+if (ix == iy) return 0;
+if (isNaN(x)) return 1;
+if (isNaN(y)) return -1;
+int ix_sign = ix>>31;
+int iy_sign = iy>>31;
+if (ix_sign == iy_sign) {
+  return x > y ? 1 : -1;
+} else {
+  return ix_sign - iy_sign;
+}
   }
 }