[cp-testresults] FAIL: regressions for mauve-jamvm on Mon Jul 2 07:00:30 UTC 2007
Baseline from: Mon Jun 25 16:25:44 UTC 2007 Regressions: FAIL: java.awt.Graphics.TestPaintGraphics FAIL: java.lang.Integer.parseInt FAIL: javax.swing.JLabel.AccessibleJLabel.getIndexAtPoint FAIL: javax.swing.JLabel.getActionMap FAIL: javax.swing.JLabel.getInputMap FAIL: javax.swing.JLabel.setIconTextGap FAIL: javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleStateSet FAIL: javax.swing.JList.constructors FAIL: javax.swing.JMenu.getInputMap FAIL: javax.swing.JProgressBar.getPercentComplete FAIL: javax.swing.JProgressBar.setModel FAIL: javax.swing.JTable.TableRobot FAIL: javax.swing.JTable.constructors Improvements: PASS: javax.swing.JTable.setColumnSelectionAllowed New fails: Totals: PASS: 2909 XPASS: 0 FAIL: 205 XFAIL: 0 ___ Classpath-testresults mailing list Classpath-testresults@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-testresults
[cp-testresults] FAIL: regressions for mauve-gij on Mon Jul 2 09:03:09 UTC 2007
Baseline from: Fri Jun 29 09:36:12 UTC 2007 Regressions: FAIL: java.lang.Integer.parseInt FAIL: java.lang.Thread.sleep Totals: PASS: 2903 XPASS: 0 FAIL: 230 XFAIL: 0 ___ Classpath-testresults mailing list Classpath-testresults@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-testresults
[cp-testresults] FAIL: regressions for mauve-jamvm on Mon Jul 2 16:48:03 UTC 2007
Baseline from: Mon Jun 25 16:25:44 UTC 2007 Regressions: FAIL: java.lang.Integer.parseInt FAIL: java.lang.Thread.sleep FAIL: javax.swing.JComponent.constructor FAIL: javax.swing.JFrame.SetSize FAIL: javax.swing.JLabel.AccessibleJLabel.getIndexAtPoint FAIL: javax.swing.JLabel.getActionMap FAIL: javax.swing.JLabel.getInputMap FAIL: javax.swing.JLabel.setIconTextGap FAIL: javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleStateSet FAIL: javax.swing.JList.constructors FAIL: javax.swing.JMenu.getInputMap FAIL: javax.swing.JProgressBar.getPercentComplete FAIL: javax.swing.JProgressBar.setModel FAIL: javax.swing.JTable.TableRobot FAIL: javax.swing.JTable.constructors Improvements: PASS: javax.swing.JTable.setColumnSelectionAllowed New fails: Totals: PASS: 2907 XPASS: 0 FAIL: 207 XFAIL: 0 ___ Classpath-testresults mailing list Classpath-testresults@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-testresults
[cp-testresults] FAIL: regressions for mauve-gij on Mon Jul 2 18:53:03 UTC 2007
Baseline from: Fri Jun 29 09:36:12 UTC 2007 Regressions: FAIL: java.lang.Integer.parseInt FAIL: javax.net.ssl.SSLEngine.TestHandshake Totals: PASS: 2903 XPASS: 0 FAIL: 230 XFAIL: 0 ___ Classpath-testresults mailing list Classpath-testresults@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-testresults
[cp-testresults] FAIL: regressions for mauve-gij on Tue Jul 3 04:36:23 UTC 2007
Baseline from: Fri Jun 29 09:36:12 UTC 2007 Regressions: FAIL: java.lang.Integer.parseInt Totals: PASS: 2904 XPASS: 0 FAIL: 229 XFAIL: 0 ___ Classpath-testresults mailing list Classpath-testresults@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-testresults
Re: Float/Double compare
Ian Rogers writes: Ian Rogers wrote: 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; } Below is a variant of the compare code and a comparison with the cost of the current compare code: public static int compare(float x, float y) { int ix = floatAsIntBits(x); int iy = floatAsIntBits(y); if (ix == iy) return 0; if (isNaN(x)) return 1; if (isNaN(y)) return -1; int ix_sign = ix31; int iy_sign = iy31; if (ix_sign == iy_sign) { return x y ? 1 : -1; } else { return ix_sign - iy_sign; } } Case: x == y neither are NaN or 0.0 New Cost: 2 float as ints, 1 int compare Old Cost: 5 float compares Case: x y and different sign New Cost: 2 float as ints, 2 int compares, 2 float compares, 2 shifts, one subtract Old Cost: 6 float compares Case: x y and same sign New Cost: 2 float as ints, 2 int compares, 3 float compares, 2 shifts Old Cost: 6 float compares Case: x is NaN New Cost: 2 float as ints, 1 int compare, 1 float compare Old Cost: 2 float compares Case: y is NaN New Cost: 2 float as ints, 1 int compare, 2 float compares Old Cost: 2 float compares Case: x == 0.0 and y == 0.0 New Cost: either 2 float as ints, 1 int compare or 2 float as ints, 2 int compares, 2 float compares, 2 shifts, one subtract Old Cost: 4 float compares, 2 float divides, 1 float subtract, 1 float to int The same code but for doubles would be: public static int compare(double x, double y) { long lx = doubleAsLongBits(x); long ly = doubleAsLongBits(y); if (lx == ly) return 0; if (isNaN(x)) return 1; if (isNaN(y)) return -1; int lx_sign = (int)(lx63); int ly_sign = (int)(ly63); if (lx_sign == ly_sign) { return x y ? 1 : -1; } else { return lx_sign - ly_sign; } } So the case when y is a NaN is slower with the new code but I think all of the more common cases are similar or faster. Of course it depends on the speed of all the operations. If you cared about a CPU with no floating point, the new code is a lot faster. If you've got great floating point and a lot of cases of y being a NaN the old code will be better. My guess is that in the general case the new code wins out. There may be a bug I can't see in this code :-) We know that any calculation involving NaN returns false, right? So, simple cases can be done first without the (possibly expensive) move out of the FPU: if (x y) return -1; if (x y) return 1; then you can do the doubleToLongBits: long lx = doubleAsLongBits(x); long ly = doubleAsLongBits(y); if (lx == ly) return 0; At this point we know they're unequal. Also, either one of them is NaN, or one of them is -0 and the other +0. Java's doubleToLongBits alwayse uses the canonical NaN, so we know that they can't both be NaN. if (lx ly) return -1; return 1; Andrew.
Re: Float/Double compare
Andrew Haley wrote: We know that any calculation involving NaN returns false, right? So, simple cases can be done first without the (possibly expensive) move out of the FPU: if (x y) return -1; if (x y) return 1; then you can do the doubleToLongBits: long lx = doubleAsLongBits(x); long ly = doubleAsLongBits(y); if (lx == ly) return 0; At this point we know they're unequal. Also, either one of them is NaN, or one of them is -0 and the other +0. Java's doubleToLongBits alwayse uses the canonical NaN, so we know that they can't both be NaN. if (lx ly) return -1; return 1; Hi Andrew, this is great. I'd forgotten about the NaN test buried in doubleToLongBits, and I like the logic to push the and tests to the top. Using these insights I've tried to figure if there's a better way than this and I just wonder whether as the long bits conversions do a NaN test is the following cheaper: // handle the easy cases: if (x y) return -1; if (x y) return 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; Although its almost certain a VM can do better with a VM specific implementation. For example, on Intel you can reuse the fact that a floating point compare gives you unordered information (in fact in many cases you need to test for this anyway). I imagine GCC is better at doing this kind of machine specific optimization than most JITs are. Regards, Ian
Re: Float/Double compare
Ian Rogers writes: Andrew Haley wrote: We know that any calculation involving NaN returns false, right? So, simple cases can be done first without the (possibly expensive) move out of the FPU: if (x y) return -1; if (x y) return 1; then you can do the doubleToLongBits: long lx = doubleAsLongBits(x); long ly = doubleAsLongBits(y); if (lx == ly) return 0; At this point we know they're unequal. Also, either one of them is NaN, or one of them is -0 and the other +0. Java's doubleToLongBits alwayse uses the canonical NaN, so we know that they can't both be NaN. if (lx ly) return -1; return 1; Hi Andrew, this is great. I'd forgotten about the NaN test buried in doubleToLongBits, and I like the logic to push the and tests to the top. Using these insights I've tried to figure if there's a better way than this and I just wonder whether as the long bits conversions do a NaN test is the following cheaper: // handle the easy cases: if (x y) return -1; if (x y) return 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; It probably is cheaper, yes. Andrew.