
                        //#pragma warning(disable : 4996)
//#pragma warning(disable : 4793)

/*
 *     C/C++ Whetstone Benchmark Single or Double Precision
 *
 *  #define Precision and Version not used
 *
 *  Different compilers can produce different floating point numeric
 *  results, probably due to compiling instructions in a different
 *  sequence. As the program checks these, they may need to be changed.
 *  The log file indicates non-standard results and these values can
 *  be copied and pasted into this program. See // Values near the
 *  end of main(). These values are for optimised compiling and non-
 *  optimised results might be different.
 *
 *  Different compilers do not optimise the code in the same way.
 *  This can lead to wide variations in benchmark speeds. See results
 *  with MS6 compiler ID and compare with those from same CPUs from
 *  the Watcom compiler generated code.
 *
 */

/* debug

   C/C++ Whetstone Benchmark

Calibrate
       0.02 Seconds          1   Passes (x 100)
       0.08 Seconds          5   Passes (x 100)
       0.42 Seconds         25   Passes (x 100)

Use 598  passes (x 100)

   C/C++ Whetstone Benchmark


Loop content                  Result              MFLOPS      MOPS   Seconds

N1 floating point     -1.12475025653839110       444.809              0.026
N2 floating point     -1.12274754047393800       364.629              0.220
N3 if then else        1.00000000000000000                 622.365    0.099
N4 fixed point        12.00000000000000000                 773.576    0.244
N5 sin,cos etc.        0.49907419085502625                  20.946    2.375
N6 floating point      0.99999988079071045       100.049              3.224
N7 assignments         3.00000000000000000                  68.113    1.622
N8 exp,sqrt etc.       0.75110626220703125                  10.776    2.064

MWIPS                                            605.551              9.875

*/

/* release

   C/C++ Whetstone Benchmark

Calibrate
       0.02 Seconds          1   Passes (x 100)
       0.03 Seconds          5   Passes (x 100)
       0.16 Seconds         25   Passes (x 100)
       0.82 Seconds        125   Passes (x 100)

Use 1532  passes (x 100)

   C/C++ Whetstone Benchmark


Loop content                  Result              MFLOPS      MOPS   Seconds

N1 floating point     -1.12475025653839110       432.863              0.068
N2 floating point     -1.12274754047393800       437.708              0.470
N3 if then else        1.00000000000000000                1640.972    0.097
N4 fixed point        12.00000000000000000                1566.384    0.308
N5 sin,cos etc.        0.49907419085502625                  39.028    3.266
N6 floating point      0.99999988079071045       270.063              3.060
N7 assignments         3.00000000000000000                 640.487    0.442
N8 exp,sqrt etc.       0.75110626220703125                  24.927    2.286

MWIPS                                           1532.439              9.997

*/

/* release with  /EHa  and /clr
   C/C++ Whetstone Benchmark

Calibrate
       0.01 Seconds          1   Passes (x 100)
       0.04 Seconds          5   Passes (x 100)
       0.19 Seconds         25   Passes (x 100)
       0.96 Seconds        125   Passes (x 100)

Use 1299  passes (x 100)

   C/C++ Whetstone Benchmark


Loop content                  Result              MFLOPS      MOPS   Seconds

N1 floating point     -1.12475025653839110       448.245              0.056
N2 floating point     -1.12274754047393800       178.428              0.978
N3 if then else        1.00000000000000000                1327.804    0.101
N4 fixed point        12.00000000000000000                1439.574    0.284
N5 sin,cos etc.        0.49907419085502625                  41.604    2.598
N6 floating point      0.99999988079071045       195.374              3.586
N7 assignments         3.00000000000000000                 645.571    0.372
N8 exp,sqrt etc.       0.75110614299774170                  23.930    2.019

MWIPS                                           1299.655              9.995

*/

 #include <math.h>       /* for sin, exp etc.           */
 #include <stdio.h>      /* standard I/O                */
 #include <conio.h>      /* for getch  - 2 occurrences  */
 #include <string.h>     /* for strcpy - 1 occurrence   */
 #include <stdlib.h>     /* for exit   - 1 occurrence   */
 #include <windows.h>
 #include <time.h>

 // PRECISION
 #ifdef DP
    #define SPDP double
    #define Precision "Double Precision"
    #define SorD "2"
 #else
    #define SPDP float
//    #define Precision "Single Precision"
    #define Precision " "
   #define SorD "1"
 #endif

 // VERSION
 #ifdef CNNT
    #define options   "Non-optimised"
    #define opt "0"
 #else
//    #define options   "Optimised"
    #define options   " "
    #define opt "1"
 #endif

  void whetstones(long xtra, long x100, int calibrate);
  void pa(SPDP e[4], SPDP t, SPDP t2);
  void po(SPDP e1[4], long j, long k, long l);
  void p3(SPDP *x, SPDP *y, SPDP *z, SPDP t, SPDP t1, SPDP t2);
  void start_time();
  double end_time();
  void local_time();



  static SPDP loop_time[9];
  static SPDP loop_mops[9];
  static SPDP loop_mflops[9];
  static SPDP TimeUsed;
  static SPDP mwips;
  static char  headings[9][18];
  static SPDP Check;
  static SPDP results[9];

  double secs;
  LARGE_INTEGER starttime;
  char    timeday[30];
  char    configData1[200];
  char    configData2[200];
  char    configData3[200];
  char    configData4[200];
  int     hasMMX;
  unsigned int megaHz;
  DWORD   ramsize;
  DWORD   freesize;
  char idString[20];
  unsigned int eaxCode;
  unsigned int eaxCode1;
  unsigned int edxCode;
  unsigned int startCount;
  unsigned int endCount;

 #define MM_EXTENSION 0x00800000


int  testmain()
  {
	   int count = 10, calibrate = 1;
	   long xtra=1;
	   int endit;
	   int i;
	   int errors;
	   long x100 = 100;
	   int duration = 10;
	   double gmean1;
	   double gmean2;
	   char expect[9][30];
	   char was[30];


	   local_time();

	   do
	   {
			TimeUsed=0;

			whetstones(xtra,x100,calibrate);

			calibrate = calibrate + 1;
			count = count - 1;
			if (TimeUsed > 0.2)
			   count = 0;
			else
			   xtra = xtra * 5;
	   }
	   while (count > 0);

	   if (TimeUsed > 0)
		 xtra = (long)((SPDP)(duration * xtra) / TimeUsed);
	   if (xtra < 1) xtra = 1;

	   calibrate = 0;


	   TimeUsed=0;
	   whetstones(xtra,x100,calibrate);

	return 0;
}

void whetstones(long xtra, long x100, int calibrate)
{
	long n1,n2,n3,n4,n5,n6,n7,n8,i,ix,n1mult;
	SPDP x,y,z;
	long j,k,l;
	SPDP e1[4];
	double timeb;

	SPDP t =  (SPDP)0.49999975;
	SPDP t0 = t;
	SPDP t1 = (SPDP)0.50000025;
	SPDP t2 = 2.0;

	Check=0.0;

	n1 = 12*x100;
	n2 = 14*x100;
	n3 = 345*x100;
	n4 = 210*x100;
	n5 = 32*x100;
	n6 = 899*x100;
	n7 = 616*x100;
	n8 = 93*x100;
	n1mult = 10;

	/* Section 1, Array elements */

	e1[0] = 1.0;
	e1[1] = -1.0;
	e1[2] = -1.0;
	e1[3] = -1.0;
	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0; i<n1*n1mult; i++)
			  {
				  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;
			  }
			t = (SPDP)1.0 - t;
		  }
		t =  t0;
	}
	end_time();
	timeb = secs/(double)(n1mult);

	/* Section 2, Array as parameter */

	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0; i<n2; i++)
			  {
				 pa(e1,t,t2);
			  }
			t = (SPDP)1.0 - t;
		  }
		t =  t0;
	}
	end_time();
	timeb = secs;

	/* Section 3, Conditional jumps */
	j = 1;
	start_time();
	 {
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0; i<n3; i++)
			  {
				 if(j==1)       j = 2;
				 else           j = 3;
				 if(j>2)        j = 0;
				 else           j = 1;
				 if(j<1)        j = 1;
				 else           j = 0;
			  }
		  }
	 }
	end_time();
	timeb = secs;

	/* Section 4, Integer arithmetic */
	j = 1;
	k = 2;
	l = 3;
	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0; i<n4; i++)
			  {
				 j = j *(k-j)*(l-k);
				 k = l * k - (l-j) * k;
				 l = (l-k) * (k+j);
				 e1[l-2] = (SPDP)(j + k + l);
				 e1[k-2] = (SPDP)(j * k * l);
			  }
		  }
	}
	end_time();
	timeb = secs;
	x = e1[0]+e1[1];

	/* Section 5, Trig functions */
	x = 0.5;
	y = 0.5;
	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=1; i<n5; i++)
			  {
				 x = (SPDP)(t*atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0)));
				 y = (SPDP)(t*atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0)));
			  }
			t = (SPDP)1.0 - t;
		  }
		t = t0;
	}
	end_time();
	timeb = secs;

	/* Section 6, Procedure calls */
	x = 1.0;
	y = 1.0;
	z = 1.0;
	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0; i<n6; i++)
			  {
				 p3(&x,&y,&z,t,t1,t2);
			  }
		  }
	}
	end_time();
	timeb = secs;

	/* Section 7, Array refrences */
	j = 0;
	k = 1;
	l = 2;
	e1[0] = 1.0;
	e1[1] = 2.0;
	e1[2] = 3.0;
	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0;i<n7;i++)
			  {
				 po(e1,j,k,l);
			  }
		  }
	}
	end_time();
	timeb = secs;

	/* Section 8, Standard functions */
	x = 0.75;
	start_time();
	{
		for (ix=0; ix<xtra; ix++)
		  {
			for(i=0; i<n8; i++)
			  {
				 x = (SPDP)(sqrt(exp(log(x)/t1)));
			  }
		  }
	}
	end_time();
	timeb = secs;

	return;
}


void pa(SPDP e[4], SPDP t, SPDP t2)
{
 long j;
 for(j=0;j<6;j++)
	{
	   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;
	}

 return;
}

void po(SPDP e1[4], long j, long k, long l)
{
 e1[j] = e1[k];
 e1[k] = e1[l];
 e1[l] = e1[j];
 return;
}

void p3(SPDP *x, SPDP *y, SPDP *z, SPDP t, SPDP t1, SPDP t2)
{
 *x = *y;
 *y = *z;
 *x = t * (*x + *y);
 *y = t1 * (*x + *y);
 *z = (*x + *y)/t2;
 return;
}



void start_time()
{
    QueryPerformanceCounter(&starttime);
}

double end_time()
{
    LARGE_INTEGER liDiff;
    LARGE_INTEGER liFreq;

    QueryPerformanceCounter(&liDiff);

    liDiff.QuadPart -= starttime.QuadPart;

    (void)QueryPerformanceFrequency(&liFreq);

    secs = (double)liDiff.QuadPart / (double) liFreq.QuadPart;
    return secs;
}

void local_time()
{
    time_t time_of_day;
    time_of_day = time( NULL );
    strcpy (timeday, ctime(&time_of_day)); /* timeday = date and time */
    return;
}









