public class Whetstone
{
static long begin_time,
end_time,
total_time;
/*
* Whetstone benchmark in C. This program is a translation of the
* original Algol version in "A Synthetic Benchmark" by H.J. Curnow
* and B.A. Wichman in Computer Journal, Vol 19 #1, February 1976.
Convert into java and automatic iterations by Tarquin Mills from C, by anon from Unix Hensa
* Used to test compiler optimization and floating point performance.
*
* Compile by: cc -O -s -o whet whet.c
* or: cc -O -DPOUT -s -o whet whet.c
* if output is desired.
*/
static int ITERATIONS; /* ITERATIONS/10 = Millions Whetstone instructions */
static int numberOfCycles;
static int cycleNo;
static double x1, x2, x3, x4, x, y, z[]=new double[1], t, t1, t2;
static double e1[]= new double[4];
static int i, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11;


public static double mainCalc()
{ /* initialize constants */
/*System.out.println("Start");*/
t = 0.499975;
t1 = 0.50025;
t2 = 2.0;
/* set values of module weights */
n1 = 0 * ITERATIONS;
n2 = 12 * ITERATIONS;
n3 = 14 * ITERATIONS;
n4 = 345 * ITERATIONS;
n6 = 210 * ITERATIONS;
n7 = 32 * ITERATIONS;
n8 = 899 * ITERATIONS;
n9 = 616 * ITERATIONS;
n10 = 0 * ITERATIONS;
n11 = 93 * ITERATIONS;
begin_time = System.currentTimeMillis();
for (cycleNo=1; cycleNo <= numberOfCycles; cycleNo++) {
/* MODULE 1: simple identifiers */
x1 = 1.0;
x2 = x3 = x4 = -1.0;
for(i = 1; i <= n1; i += 1) {
x1 = ( x1 + x2 + x3 - x4 ) * t;
x2 = ( x1 + x2 - x3 + x4 ) * t; // correction: x2 = ( x1 + x2 - x3 - x4 ) * t;
x3 = ( x1 - x2 + x3 + x4 ) * t; // correction: x3 = ( x1 - x2 + x3 + x4 ) * t;
x4 = (-x1 + x2 + x3 + x4 ) * t;
}
// if (cycleNo==numberOfCycles) pout(n1, n1, n1, x1, x2, x3, x4);

/* MODULE 2: array elements */
e1[0] = 1.0;
e1[1] = e1[2] = e1[3] = -1.0;
for (i = 1; i <= n2; i +=1) {
e1[0] = ( e1[0] + e1[1] + e1[2] - e1[3] ) * t;
e1[1] = ( e1[0] + e1[1] - e1[2] + e1[3] ) * t;
e1[2] = ( e1[0] - e1[1] + e1[2] + e1[3] ) * t;
e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3] ) * t;
}
// if (cycleNo==numberOfCycles) pout(n2, n3, n2, e1[0], e1[1], e1[2], e1[3]);
/* MODULE 3: array as parameter */
for (i = 1; i <= n3; i += 1)
pa(e1);
// if (cycleNo==numberOfCycles) pout(n3, n2, n2, e1[0], e1[1], e1[2], e1[3]);
/* MODULE 4: conditional jumps */
j = 1;
for (i = 1; i <= n4; i += 1) {
if (j == 1)
j = 2;
else
j = 3;
if (j > 2)
j = 0;
else
j = 1;
if (j < 1 )
j = 1;
else
j = 0;
}
// if (cycleNo==numberOfCycles) pout(n4, j, j, x1, x2, x3, x4);
/* MODULE 5: omitted */
/* MODULE 6: integer arithmetic */
j = 1;
k = 2;
l = 3;
for (i = 1; i <= n6; i += 1) {
j = j * (k - j) * (l -k);
k = l * k - (l - j) * k;
l = (l - k) * (k + j);
e1[l - 2] = j + k + l; /* C arrays are zero based */
e1[k - 2] = j * k * l;
}
// if (cycleNo==numberOfCycles) pout(n6, j, k, e1[0], e1[1], e1[2], e1[3]);
/* MODULE 7: trig. functions */
x = y = 0.5;
for(i = 1; i <= n7; i +=1) {
x = t * Math.atan(t2*Math.sin(x)*Math.cos(x)/(Math.cos(x+y)+Math.cos(x-y)-1.0));
y = t * Math.atan(t2*Math.sin(y)*Math.cos(y)/(Math.cos(x+y)+Math.cos(x-y)-1.0));
}
// if (cycleNo==numberOfCycles) pout(n7, j, k, x, x, y, y);

/* MODULE 8: procedure calls */
x = y = z[0] = 1.0;
for (i = 1; i <= n8; i +=1)
p3(x, y, z);
// if (cycleNo==numberOfCycles) pout(n8, j, k, x, y, z[0], z[0]);
/* MODULE9: array references */
j = 0;
k = 1;
l = 2;
e1[0] = 1.0;
e1[1] = 2.0;
e1[2] = 3.0;
for(i = 1; i <= n9; i++)
p0();
// if (cycleNo==numberOfCycles) pout(n9, j, k, e1[0], e1[1], e1[2], e1[3]);
/* MODULE10: integer arithmetic */
j = 2;
k = 3;
for(i = 1; i <= n10; i +=1) {
j = j + k;
k = j + k;
j = k - j;
k = k - j - j;
}
// if (cycleNo==numberOfCycles) pout(n10, j, k, x1, x2, x3, x4);
/* MODULE11: standard functions */
x = 0.75;
for(i = 1; i <= n11; i +=1)
x = Math.sqrt( Math.exp( Math.log(x) / t1));
// if (cycleNo==numberOfCycles) pout(n11, j, k, x, x, x, x);
} /* for */
end_time = System.currentTimeMillis();
System.out.println(" (time for " +numberOfCycles+ " cycles): "
+(end_time - begin_time)+ " millisec.");
return (end_time - begin_time);
} /* Main */


public static void pa(double e[])
{
int j;
j = 0;
do {
e[0] = ( e[0] + e[1] + e[2] - e[3] ) * t;
e[1] = ( e[0] + e[1] - e[2] + e[3] ) * t;
e[2] = ( e[0] - e[1] + e[2] + e[3] ) * t;
e[3] = ( -e[0] + e[1] + e[2] + e[3] ) / t2;
j += 1;}
while (j < 6);
}


public static void p3(double x,double y,double z[])
{
x = t * (x + y);
y = t * (x + y);
z[0] = (x + y) /t2;
}


public static void p0()
{
e1[j] = e1[k];
e1[k] = e1[l];
e1[l] = e1[j];
}
// public static void pout(int n, int j, int k, double x1, double x2, double x3, double x4)
// {
// System.out.println(n+"\t"+j+"\t"+k+"\t"+x1+"\t"+x2+"\t"+x3+"\t"+x4);
// }
public static void main(String[] args)
{
System.out.println("WHETSTONE - using 64-bit floating-point data");
ITERATIONS = 100; /* ITERATIONS/10 = Millions Whetstone instructions */
numberOfCycles = 100;
int numberOfRuns = 10;
float elapsedTime = 0;
float meanTime = 0;
float rating = 0;
float meanRating = 0;
int intRating = 0;
for (int runNumber=1; runNumber <= numberOfRuns; runNumber++) {
System.out.print(runNumber+ ". Test");
// Call the Whetstone benchmark procedure
// compute elapsed time
elapsedTime = (float)(mainCalc()/1000);
// sum time in milliseconds per cycle
meanTime = meanTime + (elapsedTime * 1000 / numberOfCycles);
// Calculate the Whetstone rating based on the time for
// the numbers of cycles just executed
rating = (1000 * numberOfCycles) / elapsedTime;
// Sum Whetstone rating
meanRating = meanRating + rating;
intRating = (int)rating;
// Reset no_of_cycles for the next run using ten cycles more
numberOfCycles += 10;
}
meanTime = meanTime/numberOfRuns;
meanRating = meanRating/numberOfRuns;
intRating = (int)meanRating;
System.out.println("Number of Runs " + numberOfRuns);
System.out.println("Average time per cycle " + meanTime + " millisec.");
System.out.println("Average Whetstone Rating " + intRating + " KWIPS");
}


} /* benchmarks */





 
