diff --git a/ack.c b/ack.c new file mode 100644 index 0000000..69ada96 --- /dev/null +++ b/ack.c @@ -0,0 +1,14 @@ +int a; +main() +{ + int x; + a = ack (3,12); +} + + +int ack ( int m , int n ) +{ + if ( m == 0 ) return ( n + 1 ); + else if ( n == 0 ) return ack ( m - 1 , 1 ); + else return ack ( m - 1 , ack ( m , n - 1 )); +} diff --git a/ack.cpp b/ack.cpp new file mode 100644 index 0000000..de036a4 --- /dev/null +++ b/ack.cpp @@ -0,0 +1,29 @@ +class Ack { +public: + Ack(); + ~Ack(); + int Run( int m , int n ); +}; + +Ack::Ack() +{ +} + +Ack::~Ack() +{ +} + +int Ack::Run( int m , int n ) +{ + if ( m == 0 ) return ( n + 1 ); + else if ( n == 0 ) return Run ( m - 1 , 1 ); + else return Run ( m - 1 , Run ( m , n - 1 )); +} + +int main() +{ + int b; + Ack a; + + b = a.Run ( 3 ,12 ); +} diff --git a/dhry.c b/dhry.c new file mode 100644 index 0000000..6523d2d --- /dev/null +++ b/dhry.c @@ -0,0 +1,471 @@ +/* + * + * "DHRYSTONE" Benchmark Program + * + * Version: C/1.1,12/01/84 + * + * Date: PROGRAM updated 01/06/86, COMMENTS changed 01/31/87 + * + * Author: Reinhold P. Weicher, CACM Vol 27, No 10,10/84 pg. 1013 + * Translated from ADA by Rick Richardson + * Every method to preserve ADA-likeness has been used, + * at the expense of C-ness. + * + * Compile: cc -O dhry.c -o dhrynr :No registers + * cc -O -DREG=register dhry.c -o dhry :Registers + * + * Defines: Defines are provided for old C compiler's + * which don't have enums, and can't assign structures. + * The time(2) function is library dependant; most + * return the time in seconds, but beware of some, like + * Aztec C, wich return other units. + * The LOOPS define is initially set for 50000 loops. + * If you have a machine with large integers and is + * very fast, please change this number to 500000 to + * get better accuracy. Please select the way to + * measure the execution time using the TIME define. + * For single user machines, time(2) is adequate. For + * multi-user machines where you cannot get single-user + * access, use the times(2) function. Be carefull to + * adjust the HZ parameter below for the units wich + * are returned by your times(2) function. You can + * sometimes find this in . If you have + * neither time(2) nor times(2), use a stopwatch in + * the dead of the night. + * Use a "printf" at the point marked "start timer" + * to begin your timings. DO NOT use UNIX "time(1)" + * command, as this measure the total time to + * run this program, wich will (erroneously) include + * the time to malloc(3) storage and to compute the + * time it takes to do nothing. + * + * Run: dhrynr, dhry + * + * Results: If you get any new machine/OS results, please send to: + * + * ihnp4!castor!pcrat!rick + * + * and thanks to all that do. + * + * Note: I order the list in increasing performance of the + * "with registers" benchmark. If the compiler doesn't + * provide register variables, then the benchmark + * is the same for both REG and NOREG. + * + * PLEASE: Send complete information about the machine type, + * clock speed, OS anc C manufacturer/version. If + * the machine is modified, tell me what was done. + * On UNIX, execute uname -a and cc -V to get this info. + * + * 80x8x NOTE: 80x8x benchers: please try to do all memory models + * for a particular compiler. + * + * The following program contains statements of a high-level programming + * language (C) in a distribution considered representative: + * + * assignements: 53% + * control statements: 32% + * procedure,function calls 15% + * + * 100 statements are dynamically executed. The program is balanced with + * respect to the three aspects: + * - statement type + * - operand type (for simple data types) + * - operand access + * operand global, local, parameter or constant. + * + * The combination of these three aspects is balanced only appoximately. + * + * The program does not compute anything meaningfull, but it is + * syntactically and semantically correct. + * + */ + +/* Accuracy of timings and human fatigue controlled by next two lines */ +/*#define LOOPS 50000 use this for slow or 16 bit machines */ +/* #define LOOPS 5000000 use this for faster machines */ +// #define LOOPS 25000000 /* use this for faster machines */ +#define LOOPS 100000000 /* use this for faster machines */ + +/* Compiler dependant options */ +#undef NOENUM /* define if compiler has no enums's */ +#undef NOSTRUCTASSIGN /* define if compiler can't assign structures */ + +/* define only one of the next two defines */ +/*#define TIMES /* use times(2) time function */ +#define TIME /* use time(2) time function */ + +/* define the granularity of your times(2) function (when used) */ +#define HZ 50 /* times(2) returns 1/50 second (europe?) */ +/*#define HZ 60 /* times(2) returns 1/60 second (most) */ +/*#define HZ 100 /* times(2) returns 1/100 second (WECo) */ + +/* for compatilbility with goofed up version */ +/*#undef GOOF /* define if you want the goofed up version */ + +#ifdef GOOF +char Version[] = "1.0"; +#else +char Version[] = "1.1"; +#endif + +#ifdef NOSTUCTASSIGN +#define structassign(d,s) memcpy(&(d), &(s), sizeof(d)) +#else +#define structassign(d,s) d = s +#endif + +#ifdef NOENUM +#define Ident1 1 +#define Ident2 2 +#define Ident3 3 +#define Ident4 4 +#define Ident5 5 +typedef int Enumeration; +#else +typedef enum {Ident1, Ident2, Ident3, Ident4, Ident5} Enumeration; +#endif + +typedef int OneToThirty; +typedef int OneToFifty; +typedef char CapitalLetter; +typedef char String30[31]; +typedef int Array1Dim[51]; +typedef int Array2Dim[51][51]; + +struct Record +{ + struct Record *PtrComp; + Enumeration Discr; + Enumeration EnumComp; + OneToFifty IntComp; + String30 StringComp; +}; + +typedef struct Record RecordType; +typedef RecordType * RecordPtr; +typedef int boolean; + +#define NULL 0 +#define TRUE 1 +#define FALSE 0 + +#ifndef REG +#define REG +#endif + +extern Enumeration Func1(); +extern boolean Func2(); + +#ifdef TIMES +#include +#include +#endif + +main() +{ + Proc0(); + exit(0); +} + +/* + * Package 1 + */ + +int IntGlob; +boolean BoolGlob; +char Char1Glob; +char Char2Glob; +Array1Dim Array1Glob; +Array2Dim Array2Glob; +RecordPtr PtrGlb; +RecordPtr PtrGlbNext; + +Proc0() +{ + OneToFifty IntLoc1; + REG OneToFifty IntLoc2; + OneToFifty IntLoc3; + REG char CharLoc; + REG char CharIndex; + Enumeration EnumLoc; + String30 String1Loc; + String30 String2Loc; + extern char *malloc(); +#if LOOPS == 50000 + register unsigned int i; +#else + register unsigned long i; +#endif + +#ifdef TIME + long time(); + long starttime; + long benchtime; + long nulltime; + + starttime = time((long *)0); + for(i = 0;i <= LOOPS;i++); + nulltime = time((long *)0) - starttime; /* Computes o'head of loop */ +#endif +#ifdef TIMES + time_t starttime; + time_t benchtime; + time_t nulltime; + time_t tms; + + times(&tms);starttime = tms.tms_utime; + for(i = 0;i < LOOPS;i++); + times(&tms); + nulltime = tms.tms_utime - starttime; /* Computes o'head of loop */ +#endif + + PtrGlbNext = (RecordPtr)malloc(sizeof(RecordType)); + PtrGlb = (RecordPtr)malloc(sizeof(RecordType)); + PtrGlb->PtrComp = PtrGlbNext; + PtrGlb->Discr = Ident1; + PtrGlb->EnumComp = Ident3; + PtrGlb->IntComp = 40; + strcpy(PtrGlb->StringComp, "DHRYSTONE PROGRAM,SOME STRING"); +#ifndef GOOF + strcpy(String1Loc, "DHRYSTONE PROGRAM,1'ST STRING"); /* GOOF */ +#endif + Array2Glob[8][7] = 10; /* Was missing in published program */ + +/**************** +-- Start Timer -- +****************/ +#ifdef TIME + starttime = time((long *)0); +#endif +#ifdef TIMES + times(&tms);starttime = tms.tms_utime; +#endif + + for(i = 0;i < LOOPS;i++) { + Proc5(); + Proc4(); + IntLoc1 = 2; + IntLoc2 = 3; + strcpy(String2Loc, "DHRYSTONE PROGRAM,2'ND STRING"); + EnumLoc = Ident2; + BoolGlob = !Func2(String1Loc, String2Loc); + while(IntLoc1 < IntLoc2) { + IntLoc3 = 5 * IntLoc1 - IntLoc2; + Proc7(IntLoc1, IntLoc2, &IntLoc3); + ++IntLoc1; + } + Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3); + Proc1(PtrGlb); + for(CharIndex = 'A';CharIndex <= Char2Glob;++CharIndex) + if(EnumLoc == Func1(CharIndex, 'C')) + Proc6(Ident1, &EnumLoc); + IntLoc3 = IntLoc2 * IntLoc1; + IntLoc2 = IntLoc3 / IntLoc1; + IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1; + Proc2(&IntLoc1); + } + +/*************** +-- Stop Timer -- +***************/ + +#ifdef TIME + benchtime = time((long *)0) - starttime - nulltime; + printf("Dhrystone (version %s) time for %ld passes = %ld\n", + Version, (long)LOOPS, benchtime); + printf("This machine benchmarks at %ld dhrystones/second\n", + ((long)LOOPS / benchtime)); +#endif +#ifdef TIMES + times(&tms); + benchtime = tms.tms_utime - starttime - nulltime; + printf("Dhrystone (version %s) time for %ld passes = %ld\n", + Version, (long)LOOPS, benchtime / HZ); + printf("This machine benchmarks at %ld dhrystones/second\n", + ((long)LOOPS * HZ / benchtime; +#endif +} + +Proc1(PtrParIn) +REG RecordPtr PtrParIn; +{ +#define NextRecord (*(PtrParIn->PtrComp)) + + structassign(NextRecord, *PtrGlb); + PtrParIn->IntComp = 5; + NextRecord.IntComp = PtrParIn->IntComp; + NextRecord.PtrComp = PtrParIn->PtrComp; + Proc3(NextRecord.PtrComp); + if(NextRecord.Discr == Ident1) { + NextRecord.IntComp = 6; + Proc6(PtrParIn->EnumComp, &NextRecord.EnumComp); + NextRecord.PtrComp = PtrGlb->PtrComp; + Proc7(NextRecord.IntComp, 10, &NextRecord.IntComp); + } + else + structassign(*PtrParIn, NextRecord); +#undef NextRecord +} + +Proc2(IntParIO) +OneToFifty *IntParIO; +{ + REG OneToFifty IntLoc; + REG Enumeration EnumLoc; + + IntLoc = *IntParIO + 10; + for(;;) { + if(Char1Glob == 'A') { + --IntLoc; + *IntParIO = IntLoc - IntGlob; + EnumLoc = Ident1; + } + if(EnumLoc == Ident1) break; + } +} + +Proc3(PtrParOut) +RecordPtr *PtrParOut; +{ + if(PtrGlb != NULL) + *PtrParOut = PtrGlb->PtrComp; + else + IntGlob = 100; + Proc7(10, IntGlob, &PtrGlb->IntComp); +} + +Proc4() +{ + REG boolean BoolLoc; + + BoolLoc = Char1Glob == 'A'; + BoolLoc |= BoolGlob; + Char2Glob = 'B'; +} + +Proc5() +{ + Char1Glob = 'A'; + BoolGlob = FALSE; +} + +extern boolean Func3(); + +Proc6(EnumInPar, EnumOutPar) +REG Enumeration EnumInPar; +REG Enumeration *EnumOutPar; +{ + *EnumOutPar = EnumInPar; + if(!Func3(EnumInPar)) + *EnumOutPar = Ident4; + switch(EnumInPar) { + case Ident1: + *EnumOutPar = Ident1; + break; + case Ident2: + if(IntGlob > 100) *EnumOutPar = Ident1; + else *EnumOutPar = Ident4; + break; + case Ident3: + *EnumOutPar = Ident2; + break; + case Ident4: + break; + case Ident5: + *EnumOutPar = Ident3; + } +} + +Proc7(IntParI1, IntParI2, IntParOut) +OneToFifty IntParI1; +OneToFifty IntParI2; +OneToFifty *IntParOut; +{ + REG OneToFifty IntLoc; + + IntLoc = IntParI1 + 2; + *IntParOut = IntParI2 + IntLoc; +} + +Proc8(Array1Par, Array2Par, IntParI1, IntParI2) +Array1Dim Array1Par; +Array2Dim Array2Par; +OneToFifty IntParI1; +OneToFifty IntParI2; +{ + REG OneToFifty IntLoc; + REG OneToFifty IntIndex; + + IntLoc = IntParI1 + 5; + Array1Par[IntLoc] = IntParI2; + Array1Par[IntLoc + 1] = Array1Par[IntLoc]; + Array1Par[IntLoc + 30] = IntLoc; + for(IntIndex = IntLoc;IntIndex <= (IntLoc + 1);++IntIndex) + Array2Par[IntLoc][IntIndex] = IntLoc; + ++Array2Par[IntLoc][IntLoc - 1]; + Array2Par[IntLoc + 20][IntLoc] = Array1Par[IntLoc]; + IntGlob = 5; +} + +Enumeration Func1(Char1Par, Char2Par) +CapitalLetter Char1Par; +CapitalLetter Char2Par; +{ + REG CapitalLetter Char1Loc; + REG CapitalLetter Char2Loc; + + Char1Loc = Char1Par; + Char2Loc = Char1Loc; + if(Char2Loc != Char2Par) + return(Ident1); + else + return(Ident2); +} + +boolean Func2(Str1ParI, Str2ParI) +String30 Str1ParI; +String30 Str2ParI; +{ + REG OneToThirty IntLoc; + REG CapitalLetter CharLoc; + + IntLoc = 1; + while(IntLoc <= 1) + if(Func1(Str1ParI[IntLoc], Str2ParI[IntLoc + 1]) == Ident1) { + CharLoc = 'A'; + ++IntLoc; + } + if(CharLoc >= 'W' && CharLoc <= 'Z') + IntLoc = 7; + if(CharLoc == 'X') + return(TRUE); + else { + if(strcmp(Str1ParI, Str2ParI) > 0) { + IntLoc += 7; + return(TRUE); + } + else + return(FALSE); + } +} + +boolean Func3(EnumParIn) +REG Enumeration EnumParIn; +{ + REG Enumeration EnumLoc; + + EnumLoc = EnumParIn; + if(EnumLoc == Ident3) return(TRUE); + return(FALSE); +} + +#ifdef NOSTRUCTASSIGN +memcpy(d, s, l) +register char *d; +register char *s; +register int l; +{ + while(l--) *d++ = *s++; +} +#endif diff --git a/fstones.c b/fstones.c new file mode 100644 index 0000000..fd20c5a --- /dev/null +++ b/fstones.c @@ -0,0 +1,339 @@ +/* + * + * + * Paul Stephen Borile + * + * + * d i s k s t o n e s . c : Disk performance evaluator + * + */ + +static char *Version = "1.1"; + +#include +#include +#include +#include +#include +#include + +#ifndef O_LARGEFILE +#define O_LARGEFILE 0x00 +#endif +#define B1k (1024*128) + +#define MAX_DIR_OPS 100000 + +int offset; +char block1k[B1k]; +char *block; +char str[20]; +int blksize; +int fd, fdsync; +struct stat buf; + +int start, stop; +int rnum; +int bytes; +int seekerrs = 0, readerrs = 0, writerrs = 0; + +int size; +int randsize; +int syncsize; +int lines = 0; +int totlines = 0; +int nfiles = 0; +int i,j; +int rc; +double seektime; +double servtime; + +main(argc, argv) +int argc; +char **argv; +{ + + if ( argc != 3 ) usage(argv[0]); + size = atoi(argv[2]); + syncsize = size/10; + randsize= size/10; + + block = block1k; + blksize = B1k; + bytes = size * blksize; + + memset(block, 'P', blksize); + for (i=79; (blksize-i) > 80; i+=80) { + block[i] = '\n'; + lines++; + } + block[i] = '\n'; + block[blksize-1]= '\n'; + lines +=2; + totlines = lines * size; + + printf("Phase 0 ** fstones %s - (C) 1989 Paul Stephen Borile\n", Version); + printf("Phase 1 ** Sequential file creation \n"); + printf(" Creating a %d blocks file (%d byte blocks)\n", size + , blksize); + + time(&start); + + if ((fd = open(argv[1], O_LARGEFILE|O_CREAT|O_RDWR, 0644)) == -1 ) { + perror(argv[1]); + exit(0); + } + + for (i=0; i \n", str); + exit(0); +} + +stats() +{ + printf("Total %d seek errors\n", seekerrs); + printf("Total %d read errors\n", readerrs); + printf("Total %d write errors\n", writerrs); +} diff --git a/whets.c b/whets.c new file mode 100644 index 0000000..cc187cb --- /dev/null +++ b/whets.c @@ -0,0 +1,1276 @@ +/**********************************************************/ +/* Date: Mon, 10 Mar 1997 07:38:18 -0500 */ +/* From: Roy Longbottom */ +/* Subject: WHET02.txt */ +/* To: "Alfred A. Aburto Jr." */ +/**********************************************************/ + +/* + * C/C++ Whetstone Benchmark Single or Double Precision + * + * Original concept Brian Wichmann NPL 1960's + * Original author Harold Curnow CCTA 1972 + * Self timing versions Roy Longbottom CCTA 1978/87 + * Optimisation control Bangor University 1987/90 + * C/C++ Version Roy Longbottom 1996 + * Compatibility & timers Al Aburto 1996 + * + ************************************************************ + * + * Official version approved by: + * + * Harold Curnow 100421.1615@compuserve.com + * + * Happy 25th birthday Whetstone, 21 November 1997 + * + ************************************************************ + * + * The program normally runs for about 100 seconds + * (adjustable in main - variable duration). This time + * is necessary because of poor PC clock resolution. + * The original concept included such things as a given + * number of subroutine calls and divides which may be + * changed by optimisation. For comparison purposes the + * compiler and level of optimisation should be identified. + * + ************************************************************ + * + * The original benchmark had a single variable I which + * controlled the running time. Constants with values up + * to 899 were multiplied by I to control the number + * passes for each loop. It was found that large values + * of I could overflow index registers so an extra outer + * loop with a second variable J was added. + * + * Self timing versions were produced during the early + * days. The 1978 changes supplied timings of individual + * loops and these were used later to produce MFLOPS and + * MOPS ratings. + * + * 1987 changes converted the benchmark to Fortran 77 + * standards and removed redundant IF statements and + * loops to leave the 8 active loops N1 to N8. Procedure + * P3 was changed to use global variables to avoid over- + * optimisation with the first two statements changed from + * X1=X and Y1=Y to X=Y and Y=Z. A self time calibrating + * version for PCs was also produced, the facility being + * incorporated in this version. + * + * This version has changes to avoid worse than expected + * speed ratings, due to underflow, and facilities to show + * that consistent numeric output is produced with varying + * optimisation levels or versions in different languages. + * + * Some of the procedures produce ever decreasing numbers. + * To avoid problems, variables T and T1 have been changed + * from 0.499975 and 0.50025 to 0.49999975 and 0.50000025. + * + * Each section now has its own double loop. Inner loops + * are run 100 times the loop constants. Calibration + * determines the number of outer loop passes. The + * numeric results produced in the main output are for + * one pass on the outer loop. As underflow problems were + * still likely on a processor 100 times faster than a 100 + * MHZ Pentium, three sections have T=1.0-T inserted in the + * outer loop to avoid the problem. The two loops avoid + * index register overflows. + * + * The first section is run ten times longer than required + * for accuracy in calculating MFLOPS. This time is divided + * by ten for inclusion in the MWIPS calculations. + * + * This version has facilities for typing in details of the + * particular run. This information is appended to file + * whets.res along with the results. The input section can + * be avoided using a command line parameter N (for example + * Whets.exe N). + * + * Roy Longbottom 101323.2241@compuserve.com + * + ************************************************************ + * + * Whetstone benchmark results are available in whets.tbl + * from ftp.nosc.mil/pub/aburto. The results include + * further details of the benchmarks. + * + ************************************************************ + * + * Source code is available in C/C++, Fortran, Basic and + * Visual Basic in the same format as this version. Pre- + * compiled versions for PCs are also available via C++. + * These comprise optimised and non-optimised versions + * for DOS, Windows and NT. + * + * This version compiles and runs correctly either as a + * C or CPP program with a WATCOM and Borland compiler. + * + ************************************************************ + * + * Example of initial calibration display (Pentium 100 MHz) + * + * Single Precision C/C++ Whetstone Benchmark + * + * Calibrate + * 0.17 Seconds 1 Passes (x 100) + * 0.77 Seconds 5 Passes (x 100) + * 3.70 Seconds 25 Passes (x 100) + * + * Use 676 passes (x 100) + * + * 676 passes are used for an approximate duration of 100 + * seconds, providing an initial estimate of a speed rating + * of 67.6 MWIPS. + * + * This is followed by the table of results as below. Input + * statements are then supplied to type in the run details. + * + ************************************************************ + * + * Examples of results from file whets.res + * + * Whetstone Single Precision Benchmark in C/C++ + * + * Month run 4/1996 + * PC model Escom + * CPU Pentium + * Clock MHz 100 + * Cache 256K + * H/W Options Neptune chipset + * OS/DOS Windows 95 + * Compiler Watcom C/C++ 10.5 Win386 + * Options No optimisation + * Run by Roy Longbottom + * From UK + * Mail 101323.2241@compuserve.com + * + * Loop content Result MFLOPS MOPS Seconds + * + * N1 floating point -1.12475025653839100 19.971 0.274 + * N2 floating point -1.12274754047393800 11.822 3.240 + * N3 if then else 1.00000000000000000 11.659 2.530 + * N4 fixed point 12.00000000000000000 13.962 6.430 + * N5 sin,cos etc. 0.49904659390449520 2.097 11.310 + * N6 floating point 0.99999988079071040 3.360 45.750 + * N7 assignments 3.00000000000000000 2.415 21.810 + * N8 exp,sqrt etc. 0.75110864639282230 1.206 8.790 + * + * MWIPS 28.462 100.134 + * + * Whetstone Single Precision Benchmark in C/C++ + * + * Compiler Watcom C/C++ 10.5 Win386 + * Options -otexan -zp4 -om -fp5 -5r + * + * Loop content Result MFLOPS MOPS Seconds + * + * N1 floating point -1.12475025653839100 26.751 0.478 + * N2 floating point -1.12274754047393800 17.148 5.220 + * N3 if then else 1.00000000000000000 19.922 3.460 + * N4 fixed point 12.00000000000000000 15.978 13.130 + * N5 sin,cos etc. 0.49904659390449520 2.663 20.810 + * N6 floating point 0.99999988079071040 10.077 35.650 + * N7 assignments 3.00000000000000000 22.877 5.380 + * N8 exp,sqrt etc. 0.75110864639282230 1.513 16.370 + * + * MWIPS 66.270 100.498 + * + * + * Whetstone Double Precision Benchmark in C/C++ + * + * Compiler Watcom C/C++ 10.5 Win32NT + * Options -otexan -zp4 -om -fp5 -5r + * + * Loop content Result MFLOPS MOPS Seconds + * + * N1 floating point -1.12398255667391900 26.548 0.486 + * N2 floating point -1.12187079889284400 16.542 5.460 + * N3 if then else 1.00000000000000000 19.647 3.540 + * N4 fixed point 12.00000000000000000 15.680 13.500 + * N5 sin,cos etc. 0.49902937281515140 3.019 18.520 + * N6 floating point 0.99999987890802820 9.977 36.330 + * N7 assignments 3.00000000000000000 22.620 5.490 + * N8 exp,sqrt etc. 0.75100163018457870 1.493 16.740 + * + * MWIPS 67.156 100.066 + * + * Note different numeric results to single precision. Slight variations + * are normal with different compilers and sometimes optimisation levels. + * + * + * Example Single Precision Optimised Results + * + * MWIPS MFLOPS MFLOPS MFLOPS COS EXP FIXPT IF EQUAL + * PC 1 2 3 MOPS MOPS MOPS MOPS MOPS + * + * P3 5.68 0.928 0.884 0.673 0.461 0.275 2.36 2.16 0.638 + * P4 16.4 5.09 4.03 2.66 0.526 0.342 6.36 6.00 5.28 + * P5 66.3 26.8 17.1 10.1 2.66 1.51 16.0 19.9 22.9 + * P6 161 50.3 45.2 31.5 4.46 2.77 102 20.6 119 + * + * Example Single Precision Non-optimised Results + * + * P3 3.07 0.860 0.815 0.328 0.355 0.160 1.70 1.32 0.264 + * P4 10.0 4.68 3.51 1.27 0.482 0.298 5.73 5.20 1.18 + * P5 28.5 20.0 11.8 3.36 2.10 1.21 14.0 11.7 2.42 + * P6 81.7 47.5 37.8 10.9 3.91 2.43 51.2 42.8 7.85 + * + * Summary results as in whets.tbl at ftp.nosc.mil/pub/aburto + * + * MFLOPS = Geometric Mean of three MFLOPS loops + * VAX MIPS = 5 * Geometric Mean of last three items above + * + * VAX + * PC System CPU/Options Cache MHz MWIPS MFLOPS MIPS + * + * P3 Clone AM80386DX with 387 128K 40 5.68 0.820 7.40 + * P4 Escom 80486DX2 CIS chipset 128K 66 16.4 3.79 29.3 + * P5 Escom Pentium Neptune chipset 256K 100 66.3 16.7 96.9 + * P6 Dell PentiumPro 440FX PCIset 256K 200 161 41.5 315 + * + * P3 Clone AM80386DX with 387 128K 40 3.07 0.613 4.20 + * P4 Escom 80486DX2 CIS chipset 128K 66 10.0 2.75 16.4 + * P5 Escom Pentium Neptune chipset 256K 100 28.5 9.26 36.6 + * P6 Dell PentiumPro 440FX PCIset 256K 200 81.7 26.9 129 + * + ************************************************************************** + * + * Running Instructions + * + * 1. In order to compile successfully, include timer option as + * indicated below. + * 2. If pre-compiled codes are to be distributed, compile with the + * -DPRECOMP option or uncomment #define PRECOMP at PRECOMPILE + * below. Also insert compiler name and optimisation details + * at #define precompiler and #define preoptions. + * 3. Compile and run for single precision results. Include run + * time parameter N to bipass typing in hardware details etc. + * 4. Compile with -DDP option or uncomment #define DP at PRECISION + * below and run for double precision results. + * 5. Run with maximum and no optimisation (minimum debug) + * 6. Notify Roy Longbottom of other necessary changes + * 7. Send results file whets.res to Roy Longbottom - with one + * sample of each run and system details fully completed + * + * Roy Longbottom 101323.2241@compuserve.com 6 November 1996 + * + ************************************************************************** + */ + + #include /* for sin, exp etc. */ + #include /* standard I/O */ + #include /* for strcpy - 3 occurrences */ + #include /* for exit - 1 occurrence */ + #include + +/***************************************************************/ +/* Timer options. You MUST uncomment one of the options below */ +/* or compile, for example, with the '-DUNIX' option. */ +/***************************************************************/ +/* #define Amiga */ +/* #define UNIX */ +/* #define UNIX_Old */ +/* #define VMS */ +/* #define BORLAND_C */ +/* #define MSC */ +/* #define MAC */ +/* #define IPSC */ +/* #define FORTRAN_SEC */ +/* #define GTODay */ +/* #define CTimer */ +/* #define UXPM */ +/* #define MAC_TMgr */ +/* #define PARIX */ +/* #define POSIX */ +/* #define WIN32 */ +/* #define POSIX1 */ +/***********************/ + +/*PRECISION PRECISION PRECISION PRECISION PRECISION PRECISION PRECISION*/ + + /* #define DP */ + + #ifdef DP + #define SPDP double + #define Precision "Double" + #else + #define SPDP float + #define Precision "Single" + #endif + + +/*PRECOMPILE PRECOMPILE PRECOMPILE PRECOMPILE PRECOMPILE PRECOMPILE*/ + + /* #define PRECOMP */ + + #ifdef PRECOMP + #define precompiler "INSERT COMPILER NAME HERE" + #define preoptions "INSERT OPTIMISATION OPTIONS HERE" + #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 pout(char title[22], float ops, int type, SPDP checknum, + SPDP time, int calibrate, int section); + + + 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]; + +main(int argc, char *argv[]) +{ + int count = 10, calibrate = 1; + long xtra = 1; + int section; + long x100 = 100; + int duration = 100; + FILE *outfile; + char compiler[80] = " ", options[256] = " ", general[10][80] = {" "}; + char *endit = " "; + char *getinput = "Yes"; + + printf("\n"); + printf("##########################################\n"); + printf("%s Precision C/C++ Whetstone Benchmark\n\n", Precision); + + + if (argc > 1) + { + switch (argv[1][0]) + { + case 'N': + getinput = "No"; + break; + case 'n': + getinput = "No"; + break; + } + } + if (getinput == "No") + { + printf ("No run time input data\n\n"); + } + + outfile = fopen("whets.res","a+"); + if (outfile == NULL) + { + printf ("Cannot open results file \n\n"); + printf("Press RETURN to exit\n"); + gets(endit); + exit (0); + } + + printf("Calibrate\n"); + do + { + TimeUsed=0; + + whetstones(xtra,x100,calibrate); + + printf("%11.2f Seconds %10.0lf Passes (x 100)\n", + TimeUsed,(SPDP)(xtra)); + calibrate++; + count--; + + if (TimeUsed > 2.0) + { + 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; + + printf("\nUse %d passes (x 100)\n", xtra); + + printf("\n %s Precision C/C++ Whetstone Benchmark",Precision); + + #ifdef PRECOMP + printf("\n Compiler %s", precompiler); + printf("\n Options %s\n", preoptions); + #else + printf("\n"); + #endif + + printf("\nLoop content Result MFLOPS " + " MOPS Seconds\n\n"); + + TimeUsed=0; + whetstones(xtra,x100,calibrate); + + printf("\nMWIPS "); + if (TimeUsed>0) + { + mwips=(float)(xtra) * (float)(x100) / (10 * TimeUsed); + } + else + { + mwips = 0; + } + + printf("%39.3f%19.3f\n\n",mwips,TimeUsed); + + if (Check == 0) printf("Wrong answer "); + + + + /************************************************************************/ + /* Type details of hardware, software etc. */ + /************************************************************************/ + + if (getinput == "Yes") + { + printf ("Enter the following which will be added with results to file WHETS.RES\n"); + printf ("When submitting a number of results you need only provide details once\n"); + printf ("but a cross reference such as an abbreviated CPU type would be useful.\n"); + printf ("You can kill (exit or close) the program now and no data will be added.\n\n"); + + printf ("Date: "); + gets(general[0]); + + printf ("Computer: "); + gets(general[1]); + + printf ("CPU chip: "); + gets(general[2]); + + printf ("Clock MHz: "); + gets(general[3]); + + printf ("Cache size: "); + gets(general[4]); + + printf ("H/W options:"); + gets(general[5]); + + printf ("OS version: "); + gets(general[6]); + + #ifdef PRECOMP + strcpy (compiler, precompiler); + strcpy (options, preoptions); + #else + printf ("Compiler: "); + gets(compiler); + + printf ("Options: "); + gets(options); + #endif + + printf ("Your name: "); + gets(general[7]); + + printf ("From: "); + gets(general[8]); + + printf ("Email: "); + gets(general[9]); + } + else + { + #ifdef PRECOMP + strcpy (compiler, precompiler); + strcpy (options, preoptions); + #endif + } + + /************************************************************************/ + /* Add results to output file whets.res */ + /************************************************************************/ + fprintf (outfile, "\n"); + fprintf (outfile, "##############################################\n"); + fprintf (outfile, "Whetstone %s Precision Benchmark in C/C++\n\n",Precision); + fprintf (outfile, "Date %s\n", general[0]); + fprintf (outfile, "Model %s\n", general[1]); + fprintf (outfile, "CPU %s\n", general[2]); + fprintf (outfile, "Clock MHz %s\n", general[3]); + fprintf (outfile, "Cache %s\n", general[4]); + fprintf (outfile, "H/W options %s\n", general[5]); + fprintf (outfile, "OS %s\n", general[6]); + fprintf (outfile, "Compiler %s\n", compiler); + fprintf (outfile, "Options %s\n", options); + fprintf (outfile, "Run by %s\n", general[7]); + fprintf (outfile, "From %s\n", general[8]); + fprintf (outfile, "Email %s\n", general[9]); + fprintf (outfile, "\n"); + + fprintf (outfile,"Loop content Result" + " MFLOPS MOPS Seconds\n\n"); + + for (section=1; section<9; section++) + { + fprintf (outfile, "%s %24.17f ", headings[section], + results[section]); + if (loop_mops[section] == 99999) + { + fprintf (outfile," %9.3f %9.3f\n", + loop_mflops[section], loop_time[section]); + } + else + { + fprintf (outfile, " %9.3f %9.3f\n", + loop_mops[section], loop_time[section], results[section]); + } + } + + fprintf (outfile, "\nMWIPS "); + fprintf (outfile, "%39.3f%20.3f\n\n",mwips,TimeUsed); + fprintf (outfile, "Results to load to spreadsheet "); + fprintf (outfile, " MWIPS Mflops1 Mflops2 Mflops3 Cosmops" + " Expmops Fixpmops Ifmops Eqmops\n"); + fprintf (outfile, "Results to load to spreadsheet "); + + fprintf (outfile, " %9.3f %9.3f %9.3f", mwips, loop_mflops[1], + loop_mflops[2]); + fprintf (outfile, " %9.3f %9.3f %9.3f", loop_mflops[6], + loop_mops[5], loop_mops[8]); + fprintf (outfile, " %9.3f %9.3f %9.3f\n\n", loop_mops[4], + loop_mops[3], loop_mops[7]); + + fclose (outfile); + + printf ("\n"); + printf ("A new results file will have been created in the same directory as the\n"); + printf (".EXE files if one did not already exist. If you made a mistake on input, \n"); + printf ("you can use a text editor to correct it, delete the results or copy \n"); + printf ("them to a different file name. If you intend to run multiple tests you\n"); + printf ("you may wish to rename WHETS.RES with a more informative title.\n\n"); + printf ("Please submit feedback and results files to aburto@nosc.mil or to\n"); + printf ("Roy_Longbottom@compuserve.com\n\n"); + + +} + + 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],timea,timeb, dtime(); + + SPDP t = 0.49999975; + SPDP t0 = t; + SPDP t1 = 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; + timea = dtime(); + { + for (ix=0; ix2) j = 0; + else j = 1; + if(j<1) j = 1; + else j = 0; + } + } + } + timeb = dtime()-timea; + pout("N3 if then else \0",(float)(n3*3)*(float)(xtra), + 2,(SPDP)(j),timeb,calibrate,3); + + /* Section 4, Integer arithmetic */ + j = 1; + k = 2; + l = 3; + timea = dtime(); + { + for (ix=0; ix0) + { + mflops = ops/(1000000L*time); + } + else + { + mflops = 0; + } + loop_mops[section] = 99999; + loop_mflops[section] = mflops; + printf(" %9.3f %9.3f\n", + loop_mflops[section], loop_time[section]); + } + else + { + if (time>0) + { + mops = ops/(1000000L*time); + } + else + { + mops = 0; + } + loop_mops[section] = mops; + loop_mflops[section] = 0; + printf(" %9.3f%9.3f\n", + loop_mops[section], loop_time[section]); + } + } + + return; + } + + +/*****************************************************/ +/* Various timer routines. */ +/* Al Aburto, aburto@nosc.mil, 18 Feb 1997 */ +/* */ +/* t = dtime() outputs the current time in seconds. */ +/* Use CAUTION as some of these routines will mess */ +/* up when timing across the hour mark!!! */ +/* */ +/* For timing I use the 'user' time whenever */ +/* possible. Using 'user+sys' time is a separate */ +/* issue. */ +/* */ +/* Example Usage: */ +/* [timer options added here] */ +/* main() */ +/* { */ +/* double starttime,benchtime,dtime(); */ +/* */ +/* starttime = dtime(); */ +/* [routine to time] */ +/* benchtime = dtime() - starttime; */ +/* } */ +/* */ +/* [timer code below added here] */ +/*****************************************************/ + +/*********************************/ +/* Timer code. */ +/*********************************/ +/*******************/ +/* Amiga dtime() */ +/*******************/ +#ifdef Amiga +#include +#define HZ 50 + +SPDP dtime() +{ + SPDP q; + + struct tt + { + long days; + long minutes; + long ticks; + } tt; + + DateStamp(&tt); + + q = ((SPDP)(tt.ticks + (tt.minutes * 60L * 50L))) / (SPDP)HZ; + + return q; +} +#endif + +/*****************************************************/ +/* UNIX dtime(). This is the preferred UNIX timer. */ +/* Provided by: Markku Kolkka, mk59200@cc.tut.fi */ +/* HP-UX Addition by: Bo Thide', bt@irfu.se */ +/*****************************************************/ +#ifdef UNIX +#include +#include + +#ifdef hpux +#include +#define getrusage(a,b) syscall(SYS_getrusage,a,b) +#endif + +struct rusage rusage; + +SPDP dtime() +{ + SPDP q; + + getrusage(RUSAGE_SELF,&rusage); + + q = (SPDP)(rusage.ru_utime.tv_sec); + q = q + (SPDP)(rusage.ru_utime.tv_usec) * 1.0e-06; + + return q; +} +#endif + +/***************************************************/ +/* UNIX_Old dtime(). This is the old UNIX timer. */ +/* Use only if absolutely necessary as HZ may be */ +/* ill defined on your system. */ +/***************************************************/ +#ifdef UNIX_Old +#include +#include +#include + +#ifndef HZ +#define HZ 60 +#endif + +struct tms tms; + +SPDP dtime() +{ + SPDP q; + + times(&tms); + + q = (SPDP)(tms.tms_utime) / (SPDP)HZ; + + return q; +} +#endif + +/*********************************************************/ +/* VMS dtime() for VMS systems. */ +/* Provided by: RAMO@uvphys.phys.UVic.CA */ +/* Some people have run into problems with this timer. */ +/*********************************************************/ +#ifdef VMS +#include time + +#ifndef HZ +#define HZ 100 +#endif + +struct tbuffer_t + { + int proc_user_time; + int proc_system_time; + int child_user_time; + int child_system_time; + }; +struct tbuffer_t tms; + +SPDP dtime() +{ + SPDP q; + + times(&tms); + + q = (SPDP)(tms.proc_user_time) / (SPDP)HZ; + + return q; +} +#endif + +/******************************/ +/* BORLAND C dtime() for DOS */ +/******************************/ +#ifdef BORLAND_C +#include +#include +#include + +#define HZ 100 +struct time tnow; + +SPDP dtime() +{ + SPDP q; + + gettime(&tnow); + + q = 60.0 * (SPDP)(tnow.ti_min); + q = q + (SPDP)(tnow.ti_sec); + q = q + (SPDP)(tnow.ti_hund)/(SPDP)HZ; + + return q; +} +#endif + +/***************************************/ +/* Microsoft C (MSC) dtime() for DOS */ +/* Also suitable for Watcom C/C++ and */ +/* some other PC compilers */ +/***************************************/ +#ifdef MSC +#include +#include + +#define HZ CLOCKS_PER_SEC +clock_t tnow; + +SPDP dtime() +{ + SPDP q; + + tnow = clock(); + q = (SPDP)tnow / (SPDP)HZ; + return q; +} +#endif + +/*************************************/ +/* Macintosh (MAC) Think C dtime() */ +/*************************************/ +#ifdef MAC +#include + +#define HZ 60 + +SPDP dtime() +{ + SPDP q; + + q = (SPDP)clock() / (SPDP)HZ; + + return q; +} +#endif + +/************************************************************/ +/* iPSC/860 (IPSC) dtime() for i860. */ +/* Provided by: Dan Yergeau, yergeau@gloworm.Stanford.EDU */ +/************************************************************/ +#ifdef IPSC +extern double dclock(); + +SPDP dtime() +{ + SPDP q; + + q = dclock(); + + return q; +} +#endif + +/**************************************************/ +/* FORTRAN dtime() for Cray type systems. */ +/* This is the preferred timer for Cray systems. */ +/**************************************************/ +#ifdef FORTRAN_SEC + +fortran double second(); + +SPDP dtime() +{ + SPDP q; + + second(&q); + + return q; +} +#endif + +/***********************************************************/ +/* UNICOS C dtime() for Cray UNICOS systems. Don't use */ +/* unless absolutely necessary as returned time includes */ +/* 'user+system' time. Provided by: R. Mike Dority, */ +/* dority@craysea.cray.com */ +/***********************************************************/ +#ifdef CTimer +#include + +SPDP dtime() +{ + SPDP q; + clock_t clock(void); + + q = (SPDP)clock() / (SPDP)CLOCKS_PER_SEC; + + return q; +} +#endif + +/********************************************/ +/* Another UNIX timer using gettimeofday(). */ +/* However, getrusage() is preferred. */ +/********************************************/ +#ifdef GTODay +#include + +struct timeval tnow; + +SPDP dtime() +{ + SPDP q; + + gettimeofday(&tnow,NULL); + q = (SPDP)tnow.tv_sec + (SPDP)tnow.tv_usec * 1.0e-6; + + return q; +} +#endif + +/*****************************************************/ +/* Fujitsu UXP/M timer. */ +/* Provided by: Mathew Lim, ANUSF, M.Lim@anu.edu.au */ +/*****************************************************/ +#ifdef UXPM +#include +#include +struct tmsu rusage; + +SPDP dtime() +{ + SPDP q; + + timesu(&rusage); + + q = (SPDP)(rusage.tms_utime) * 1.0e-06; + + return q; +} +#endif + +/**********************************************/ +/* Macintosh (MAC_TMgr) Think C dtime() */ +/* requires Think C Language Extensions or */ +/* #include in the prefix */ +/* provided by Francis H Schiffer 3rd (fhs) */ +/* skipschiffer@genie.geis.com */ +/**********************************************/ +#ifdef MAC_TMgr +#include +#include + +static TMTask mgrTimer; +static Boolean mgrInited = false; +static SPDP mgrClock; + +#define RMV_TIMER RmvTime( (QElemPtr)&mgrTimer ) +#define MAX_TIME 1800000000L +/* MAX_TIME limits time between calls to */ +/* dtime( ) to no more than 30 minutes */ +/* this limitation could be removed by */ +/* creating a completion routine to sum */ +/* 30 minute segments (fhs 1994 feb 9) */ + +static void Remove_timer( ) +{ + RMV_TIMER; + mgrInited = false; +} + +SPDP dtime( ) +{ + if( mgrInited ) { + RMV_TIMER; + mgrClock += (MAX_TIME + mgrTimer.tmCount)*1.0e-6; + } else { + if( _atexit( &Remove_timer ) == 0 ) mgrInited = true; + mgrClock = 0.0; +} + if( mgrInited ) { + mgrTimer.tmAddr = NULL; + mgrTimer.tmCount = 0; + mgrTimer.tmWakeUp = 0; + mgrTimer.tmReserved = 0; + InsTime( (QElemPtr)&mgrTimer ); + PrimeTime( (QElemPtr)&mgrTimer, -MAX_TIME ); + } + return( mgrClock ); +} +#endif + +/***********************************************************/ +/* Parsytec GCel timer. */ +/* Provided by: Georg Wambach, gw@informatik.uni-koeln.de */ +/***********************************************************/ +#ifdef PARIX +#include + +SPDP dtime() +{ + SPDP q; + + q = (SPDP) (TimeNowHigh()) / (SPDP) CLK_TCK_HIGH; + + return q; +} +#endif + +/************************************************/ +/* Sun Solaris POSIX dtime() routine */ +/* Provided by: Case Larsen, CTLarsen.lbl.gov */ +/************************************************/ +#ifdef POSIX +#include +#include +#include + +#ifdef __hpux +#include +#endif + +struct rusage rusage; + +SPDP dtime() +{ + SPDP q; + + getrusage(RUSAGE_SELF,&rusage); + + q = (SPDP)(rusage.ru_utime.tv_sec); + q = q + (SPDP)(rusage.ru_utime.tv_nsec) * 1.0e-09; + + return q; +} +#endif + + +/****************************************************/ +/* Windows NT (32 bit) dtime() routine */ +/* Provided by: Piers Haken, piersh@microsoft.com */ +/****************************************************/ +#ifdef WIN32 +#include + +SPDP dtime(void) +{ + SPDP q; + + q = (SPDP)GetTickCount() * 1.0e-03; + + return q; +} +#endif + +/*****************************************************/ +/* Time according to POSIX.1 - */ +/* Ref: "POSIX Programmer's Guide" O'Reilly & Assoc.*/ +/*****************************************************/ +#ifdef POSIX1 +#define _POSIX_SOURCE 1 +#include +#include +#include + +struct tms tms; + +SPDP dtime() +{ + SPDP q; + times(&tms); + q = (SPDP)tms.tms_utime / (SPDP)CLK_TCK; + return q; +} +#endif