-
Bug
-
Resolution: Fixed
-
P3
-
1.4.1_03
-
b65
-
sparc
-
solaris_8
it seems that code calling the floatToIntBits function is running very slow on solaris boxes compared to windows machines. the function in question is Float.floatToIntBits which is performing very badly if the argument is NaN (seems that this happens in an automatically generated piece of code, therefore he claims not to be able to change it).
find attached an example program proving this behaviour. i ran it on my win box and on a solaris machine with the following results for doTestNaN on java 1.4 vm:
win 2k on pentium iii, 600 mhz cpu (not really a performance beast!):
~ 1700 ms
solaris 8 on sun fire 280r:
~ 27000 ms
any hints and tips to improve this situation welcome!
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile and run the following code:
/*
* Created on Mar 31, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
//package org.ninjoworkstation.server.benchmark.util;
/**
* @author zub
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class FloatToIntBitsTest {
private final static int REPEAT = 10000000;
public FloatToIntBitsTest() {
testNaNToIntBits();
testZeroToIntBits();
testAnyToIntBits();
invtestNaNToIntBits();
invtestZeroToIntBits();
invtestAnyToIntBits();
}
public void testNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doTestNaN():\t" + (endTime - startTime));
}
private void doTestNaN() {
int result;
float nan = Float.NaN;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(nan);
}
}
public void testZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doTestZero();
endTime = System.currentTimeMillis();
System.out.println("doTestZero():\t" + (endTime - startTime));
}
private void doTestZero() {
int result;
float zero = 0.0f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(zero);
}
}
public void testAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doTestAny();
endTime = System.currentTimeMillis();
System.out.println("doTestAny():\t" + (endTime - startTime));
}
private void doTestAny() {
int result;
float any = 12.345678f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(any);
}
}
public void invtestNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doInvTestNaN():\t" + (endTime - startTime));
}
private void doInvTestNaN() {
float result;
int nanInt = Float.floatToIntBits(Float.NaN);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(nanInt);
}
}
public void invtestZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestZero();
endTime = System.currentTimeMillis();
System.out.println("doInvTestZero():\t" + (endTime - startTime));
}
private void doInvTestZero() {
float result;
int zeroInt = Float.floatToIntBits(0.0f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(zeroInt);
}
}
public void invtestAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestAny();
endTime = System.currentTimeMillis();
System.out.println("doInvTestAny():\t" + (endTime - startTime));
}
private void doInvTestAny() {
float result;
int anyInt = Float.floatToIntBits(12.345678f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(anyInt);
}
}
public static void main(String args[]) {
new FloatToIntBitsTest();
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
expect a significantly lower computing time for the function, especially since the return value for NaN is clearly specified for the function.
performance on windows platform is ok.
ACTUAL -
similar performance on windows and on solaris platform.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* Created on Mar 31, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
//package org.ninjoworkstation.server.benchmark.util;
/**
* @author zub
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class FloatToIntBitsTest {
private final static int REPEAT = 10000000;
public FloatToIntBitsTest() {
testNaNToIntBits();
testZeroToIntBits();
testAnyToIntBits();
invtestNaNToIntBits();
invtestZeroToIntBits();
invtestAnyToIntBits();
}
public void testNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doTestNaN():\t" + (endTime - startTime));
}
private void doTestNaN() {
int result;
float nan = Float.NaN;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(nan);
}
}
public void testZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doTestZero();
endTime = System.currentTimeMillis();
System.out.println("doTestZero():\t" + (endTime - startTime));
}
private void doTestZero() {
int result;
float zero = 0.0f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(zero);
}
}
public void testAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doTestAny();
endTime = System.currentTimeMillis();
System.out.println("doTestAny():\t" + (endTime - startTime));
}
private void doTestAny() {
int result;
float any = 12.345678f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(any);
}
}
public void invtestNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doInvTestNaN():\t" + (endTime - startTime));
}
private void doInvTestNaN() {
float result;
int nanInt = Float.floatToIntBits(Float.NaN);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(nanInt);
}
}
public void invtestZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestZero();
endTime = System.currentTimeMillis();
System.out.println("doInvTestZero():\t" + (endTime - startTime));
}
private void doInvTestZero() {
float result;
int zeroInt = Float.floatToIntBits(0.0f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(zeroInt);
}
}
public void invtestAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestAny();
endTime = System.currentTimeMillis();
System.out.println("doInvTestAny():\t" + (endTime - startTime));
}
private void doInvTestAny() {
float result;
int anyInt = Float.floatToIntBits(12.345678f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(anyInt);
}
}
public static void main(String args[]) {
new FloatToIntBitsTest();
}
}
###@###.### 2004-04-26
------------------------------------------
tried it with 1.5. as it is available for download today, have the same results however.
furthermore, will try to propose the work around to the customer.
thanks a lot for your input, cheers
bernard
###@###.### 2004-04-27
find attached an example program proving this behaviour. i ran it on my win box and on a solaris machine with the following results for doTestNaN on java 1.4 vm:
win 2k on pentium iii, 600 mhz cpu (not really a performance beast!):
~ 1700 ms
solaris 8 on sun fire 280r:
~ 27000 ms
any hints and tips to improve this situation welcome!
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile and run the following code:
/*
* Created on Mar 31, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
//package org.ninjoworkstation.server.benchmark.util;
/**
* @author zub
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class FloatToIntBitsTest {
private final static int REPEAT = 10000000;
public FloatToIntBitsTest() {
testNaNToIntBits();
testZeroToIntBits();
testAnyToIntBits();
invtestNaNToIntBits();
invtestZeroToIntBits();
invtestAnyToIntBits();
}
public void testNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doTestNaN():\t" + (endTime - startTime));
}
private void doTestNaN() {
int result;
float nan = Float.NaN;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(nan);
}
}
public void testZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doTestZero();
endTime = System.currentTimeMillis();
System.out.println("doTestZero():\t" + (endTime - startTime));
}
private void doTestZero() {
int result;
float zero = 0.0f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(zero);
}
}
public void testAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doTestAny();
endTime = System.currentTimeMillis();
System.out.println("doTestAny():\t" + (endTime - startTime));
}
private void doTestAny() {
int result;
float any = 12.345678f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(any);
}
}
public void invtestNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doInvTestNaN():\t" + (endTime - startTime));
}
private void doInvTestNaN() {
float result;
int nanInt = Float.floatToIntBits(Float.NaN);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(nanInt);
}
}
public void invtestZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestZero();
endTime = System.currentTimeMillis();
System.out.println("doInvTestZero():\t" + (endTime - startTime));
}
private void doInvTestZero() {
float result;
int zeroInt = Float.floatToIntBits(0.0f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(zeroInt);
}
}
public void invtestAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestAny();
endTime = System.currentTimeMillis();
System.out.println("doInvTestAny():\t" + (endTime - startTime));
}
private void doInvTestAny() {
float result;
int anyInt = Float.floatToIntBits(12.345678f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(anyInt);
}
}
public static void main(String args[]) {
new FloatToIntBitsTest();
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
expect a significantly lower computing time for the function, especially since the return value for NaN is clearly specified for the function.
performance on windows platform is ok.
ACTUAL -
similar performance on windows and on solaris platform.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* Created on Mar 31, 2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
//package org.ninjoworkstation.server.benchmark.util;
/**
* @author zub
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class FloatToIntBitsTest {
private final static int REPEAT = 10000000;
public FloatToIntBitsTest() {
testNaNToIntBits();
testZeroToIntBits();
testAnyToIntBits();
invtestNaNToIntBits();
invtestZeroToIntBits();
invtestAnyToIntBits();
}
public void testNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doTestNaN():\t" + (endTime - startTime));
}
private void doTestNaN() {
int result;
float nan = Float.NaN;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(nan);
}
}
public void testZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doTestZero();
endTime = System.currentTimeMillis();
System.out.println("doTestZero():\t" + (endTime - startTime));
}
private void doTestZero() {
int result;
float zero = 0.0f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(zero);
}
}
public void testAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doTestAny();
endTime = System.currentTimeMillis();
System.out.println("doTestAny():\t" + (endTime - startTime));
}
private void doTestAny() {
int result;
float any = 12.345678f;
for (int k = 0; k < REPEAT; k++) {
result = Float.floatToIntBits(any);
}
}
public void invtestNaNToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestNaN();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestNaN();
endTime = System.currentTimeMillis();
System.out.println("doInvTestNaN():\t" + (endTime - startTime));
}
private void doInvTestNaN() {
float result;
int nanInt = Float.floatToIntBits(Float.NaN);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(nanInt);
}
}
public void invtestZeroToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestZero();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestZero();
endTime = System.currentTimeMillis();
System.out.println("doInvTestZero():\t" + (endTime - startTime));
}
private void doInvTestZero() {
float result;
int zeroInt = Float.floatToIntBits(0.0f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(zeroInt);
}
}
public void invtestAnyToIntBits() {
long startTime;
long endTime;
// prerun to give JIT time to get active
doInvTestAny();
// now it gets serious
startTime = System.currentTimeMillis();
doInvTestAny();
endTime = System.currentTimeMillis();
System.out.println("doInvTestAny():\t" + (endTime - startTime));
}
private void doInvTestAny() {
float result;
int anyInt = Float.floatToIntBits(12.345678f);
for (int k = 0; k < REPEAT; k++) {
result = Float.intBitsToFloat(anyInt);
}
}
public static void main(String args[]) {
new FloatToIntBitsTest();
}
}
###@###.### 2004-04-26
------------------------------------------
tried it with 1.5. as it is available for download today, have the same results however.
furthermore, will try to propose the work around to the customer.
thanks a lot for your input, cheers
bernard
###@###.### 2004-04-27
- relates to
-
JDK-6441302 performance differences in Double conversion methods between Linux and WinXP
-
- Closed
-
-
JDK-6351369 remove useless dependence on native functions {int,long}/{float,double} conversions
-
- Closed
-