-
Bug
-
Resolution: Fixed
-
P1
-
1.4.1
-
beta
-
sparc
-
solaris_8
Somwhere between build 8 and build 11, changes were made to the random number generator and the driver for ECperf is no longer generating a random sequence of requests. Here's a distillation of how the ECperf driver uses the random number generator:
import java.util.*;
public class TestRand extends Thread {
private static String alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private Random r;
public int[] buckets;
int nLoops;
TestRand(int nLoops) {
r = new Random();
buckets = new int[4];
buckets[0] = buckets[1] = buckets[2] = buckets[3] = 0;
this.nLoops = nLoops;
}
public int random(int x, int y) {
int n = r.nextInt();
while (n == Integer.MIN_VALUE)
n = r.nextInt();
int ret = ( x + (Math.abs(n) % (y - x + 1)));
return ret;
}
public double drandom(double x, double y) {
return ( x + (r.nextDouble()* (y - x)));
}
public String make_a_string(int x, int y) {
int len, i;
String str = "";
len = random(x, y);
for (i = 0; i < len; i++) {
int j = random(0, 61);
str = str + alpha.substring(j, j + 1);
}
return str;
}
public int NURand(int A, int x, int y) {
return ((random(0, A) | random(x, y)) % (y - x + 1)) + x;
}
public void run() {
for (int i = 0; i < nLoops; i++) {
int x = random(1, 100);
if (x <= 10) {
buckets[0]++;
}
else if (x <= 30) {
buckets[1]++;
}
else if (x <= 50) {
buckets[2]++;
}
else if (x <= 100) {
buckets[3]++;
make_a_string(10,20);
make_a_string(10,20);
make_a_string(10,20);
make_a_string(10,20);
make_a_string(10,20);
random(1, 100);
}
drandom(0.0, 1.0);
}
}
public static void main(String[] args) throws Exception {
int nLoops = Integer.parseInt(args[0]);
int nThreads = Integer.parseInt(args[1]);
int[] agg = new int[4];
TestRand[] tr = new TestRand[nThreads];
agg[0] = agg[1] = agg[2] = agg[3] = 0;
for (int i = 0; i < nThreads; i++) {
tr[i] = new TestRand(nLoops);
tr[i].start();
}
for (int i = 0; i < nThreads; i++) {
tr[i].join();
agg[0] += tr[i].buckets[0];
agg[1] += tr[i].buckets[1];
agg[2] += tr[i].buckets[2];
agg[3] += tr[i].buckets[3];
}
System.out.println("Distribution:\n");
System.out.println("\tBucket 1 (Expected 10%): " + ((float) agg[0]/(nLoops * nThreads)));
System.out.println("\tBucket 2 (Expected 20%): " + ((float) agg[1]/(nLoops * nThreads)));
System.out.println("\tBucket 3 (Expected 20%): " + ((float) agg[2]/(nLoops * nThreads)));
System.out.println("\tBucket 4 (Expected 50%): " + ((float) agg[3]/(nLoops * nThreads)));
}
}
Here's the output of this program under Merlin:
%java -version
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
%java -server -Xmx3500m -Xms3500m TestRand
Distribution:
Bucket 1 (Expected 10%): 0.0997714
Bucket 2 (Expected 20%): 0.2004684
Bucket 3 (Expected 20%): 0.1997232
Bucket 4 (Expected 50%): 0.500037
Here's the output with Hopper build 11:
%java -version
java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b11)
%java -server -Xmx3500m -Xms3500m TestRand
Distribution:
Bucket 1 (Expected 10%): 0.1186286
Bucket 2 (Expected 20%): 0.2264459
Bucket 3 (Expected 20%): 0.2329252
Bucket 4 (Expected 50%): 0.4220003
On an actual ECperf run (which is much longer and also more complex in its usage of the Random class), this observed distribution is .47, .08, .38, .06 [yes, the 10% bucket is getting 47% of the distribution].
====================================================================================
Although not noted above, this also causes ECPerf to fail (not just produce a
bad distribution)
JBB2000 also fails with Validation errors due to this bug. I've already confirmed
that a build from Steve containing the fix for the above test case also fixes
this problem. Here's the problem (very consistent):
...
JVM Check OK
Constructing the company now Hang....on
Loading Warehouse 1...
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 3 should be: |Customer: 17 Name: BAROUGHTANTI Credit: GC %Disc: 43.11|
Line 3 is: |Customer: 10 Name: BARBAREING Credit: GC %Disc: 12.70|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 4 should be: |Order Number: 31 Number of Lines: 15 W_tax: 10.30 D_tax: 6.62|
Line 4 is: |Order Number: 31 Number of Lines: 8 W_tax: 3.91 D_tax: 2.75|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 7 should be: | 1 12117 rk9rIQP9q52FiN4FWuihzNT 5 59 G $61.73 $308.65|
Line 7 is: | 1 5838 kLI6JutC1hODssxvj 5 44 G $46.46 $232.30|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 8 should be: | 1 19072 0VOgv21kW1ZS3pv1IzirxrmH 5 79 G $26.62 $133.10|
Line 8 is: | 1 5838 kLI6JutC1hODssxvj 5 39 G $46.46 $232.30|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 9 should be: | 1 4260 clRd7h9zm9eGwqtvKblk1q 5 53 G $85.08 $425.40|
Line 9 is: | 1 5838 kLI6JutC1hODssxvj 5 34 G $46.46 $232.30|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 10 should be: | 1 5772 b96nAb1I7qPaOA 5 73 G $50.24 $251.20
.... many others
###@###.### 2002-05-17
====================================================================================
import java.util.*;
public class TestRand extends Thread {
private static String alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private Random r;
public int[] buckets;
int nLoops;
TestRand(int nLoops) {
r = new Random();
buckets = new int[4];
buckets[0] = buckets[1] = buckets[2] = buckets[3] = 0;
this.nLoops = nLoops;
}
public int random(int x, int y) {
int n = r.nextInt();
while (n == Integer.MIN_VALUE)
n = r.nextInt();
int ret = ( x + (Math.abs(n) % (y - x + 1)));
return ret;
}
public double drandom(double x, double y) {
return ( x + (r.nextDouble()* (y - x)));
}
public String make_a_string(int x, int y) {
int len, i;
String str = "";
len = random(x, y);
for (i = 0; i < len; i++) {
int j = random(0, 61);
str = str + alpha.substring(j, j + 1);
}
return str;
}
public int NURand(int A, int x, int y) {
return ((random(0, A) | random(x, y)) % (y - x + 1)) + x;
}
public void run() {
for (int i = 0; i < nLoops; i++) {
int x = random(1, 100);
if (x <= 10) {
buckets[0]++;
}
else if (x <= 30) {
buckets[1]++;
}
else if (x <= 50) {
buckets[2]++;
}
else if (x <= 100) {
buckets[3]++;
make_a_string(10,20);
make_a_string(10,20);
make_a_string(10,20);
make_a_string(10,20);
make_a_string(10,20);
random(1, 100);
}
drandom(0.0, 1.0);
}
}
public static void main(String[] args) throws Exception {
int nLoops = Integer.parseInt(args[0]);
int nThreads = Integer.parseInt(args[1]);
int[] agg = new int[4];
TestRand[] tr = new TestRand[nThreads];
agg[0] = agg[1] = agg[2] = agg[3] = 0;
for (int i = 0; i < nThreads; i++) {
tr[i] = new TestRand(nLoops);
tr[i].start();
}
for (int i = 0; i < nThreads; i++) {
tr[i].join();
agg[0] += tr[i].buckets[0];
agg[1] += tr[i].buckets[1];
agg[2] += tr[i].buckets[2];
agg[3] += tr[i].buckets[3];
}
System.out.println("Distribution:\n");
System.out.println("\tBucket 1 (Expected 10%): " + ((float) agg[0]/(nLoops * nThreads)));
System.out.println("\tBucket 2 (Expected 20%): " + ((float) agg[1]/(nLoops * nThreads)));
System.out.println("\tBucket 3 (Expected 20%): " + ((float) agg[2]/(nLoops * nThreads)));
System.out.println("\tBucket 4 (Expected 50%): " + ((float) agg[3]/(nLoops * nThreads)));
}
}
Here's the output of this program under Merlin:
%java -version
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
%java -server -Xmx3500m -Xms3500m TestRand
Distribution:
Bucket 1 (Expected 10%): 0.0997714
Bucket 2 (Expected 20%): 0.2004684
Bucket 3 (Expected 20%): 0.1997232
Bucket 4 (Expected 50%): 0.500037
Here's the output with Hopper build 11:
%java -version
java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b11)
%java -server -Xmx3500m -Xms3500m TestRand
Distribution:
Bucket 1 (Expected 10%): 0.1186286
Bucket 2 (Expected 20%): 0.2264459
Bucket 3 (Expected 20%): 0.2329252
Bucket 4 (Expected 50%): 0.4220003
On an actual ECperf run (which is much longer and also more complex in its usage of the Random class), this observed distribution is .47, .08, .38, .06 [yes, the 10% bucket is getting 47% of the distribution].
====================================================================================
Although not noted above, this also causes ECPerf to fail (not just produce a
bad distribution)
JBB2000 also fails with Validation errors due to this bug. I've already confirmed
that a build from Steve containing the fix for the above test case also fixes
this problem. Here's the problem (very consistent):
...
JVM Check OK
Constructing the company now Hang....on
Loading Warehouse 1...
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 3 should be: |Customer: 17 Name: BAROUGHTANTI Credit: GC %Disc: 43.11|
Line 3 is: |Customer: 10 Name: BARBAREING Credit: GC %Disc: 12.70|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 4 should be: |Order Number: 31 Number of Lines: 15 W_tax: 10.30 D_tax: 6.62|
Line 4 is: |Order Number: 31 Number of Lines: 8 W_tax: 3.91 D_tax: 2.75|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 7 should be: | 1 12117 rk9rIQP9q52FiN4FWuihzNT 5 59 G $61.73 $308.65|
Line 7 is: | 1 5838 kLI6JutC1hODssxvj 5 44 G $46.46 $232.30|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 8 should be: | 1 19072 0VOgv21kW1ZS3pv1IzirxrmH 5 79 G $26.62 $133.10|
Line 8 is: | 1 5838 kLI6JutC1hODssxvj 5 39 G $46.46 $232.30|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 9 should be: | 1 4260 clRd7h9zm9eGwqtvKblk1q 5 53 G $85.08 $425.40|
Line 9 is: | 1 5838 kLI6JutC1hODssxvj 5 34 G $46.46 $232.30|
VALIDATION ERROR: incorrect output for NewOrderTransaction
Line 10 should be: | 1 5772 b96nAb1I7qPaOA 5 73 G $50.24 $251.20
.... many others
###@###.### 2002-05-17
====================================================================================