| /**********************************************************/ |
| /* Date: Mon, 10 Mar 1997 07:38:18 -0500 */ |
| /* From: Roy Longbottom <Roy_Longbottom@compuserve.com> */ |
| /* Subject: WHET02.txt */ |
| /* To: "Alfred A. Aburto Jr." <aburto@cts.com> */ |
| /**********************************************************/ |
| |
| /* |
| * 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 In fprintf(stderr,"TIMEBASE|60\n"); |
| structions |
| * |
| * 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 <math.h> /* for sin, exp etc. */ |
| #include <stdio.h> /* standard I/O */ |
| #include <string.h> /* for strcpy - 3 occurrences */ |
| #include <stdlib.h> /* for exit - 1 occurrence */ |
| |
| /***************************************************************/ |
| /* 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]; |
| |
| int main(argc, argv) |
| int argc; |
| char *argv[]; |
| { |
| int count = 10, calibrate = 1; |
| long xtra = 1; |
| long x100 = 100; |
| #ifdef UNIXBENCH |
| int duration = 10; |
| #else |
| int section; |
| int duration = 100; |
| FILE *outfile; |
| int getinput = 1; |
| char compiler[80] = " ", options[256] = " ", general[10][80] = {" "}; |
| char *endit = " "; |
| |
| printf("##########################################\n"); |
| printf("%s Precision C/C++ Whetstone Benchmark\n\n", Precision); |
| #endif |
| |
| |
| #ifndef UNIXBENCH |
| if (argc > 1) |
| { |
| switch (argv[1][0]) |
| { |
| case 'N': |
| case 'n': |
| getinput = 0; |
| break; |
| } |
| } |
| if (! getinput) |
| { |
| 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); |
| } |
| #endif |
| |
| printf("Calibrate\n"); |
| do |
| { |
| TimeUsed=0; |
| |
| whetstones(xtra,x100,calibrate); |
| |
| printf("%11.2f Seconds %10.0f Passes (x 100)\n", TimeUsed, (SPDP)(xtra)); |
| calibrate++; |
| count--; |
| |
| #ifndef UNIXBENCH |
| if (TimeUsed > 2.0) |
| #else |
| if (TimeUsed > 0.5) |
| #endif |
| { |
| 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 %ld 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. */ |
| /************************************************************************/ |
| |
| #ifndef UNIXBENCH |
| if (getinput) |
| { |
| 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"); |
| |
| #else /* Unixbench */ |
| fprintf (stderr, "COUNT|%.3f|0|MWIPS\n", mwips); |
| fprintf (stderr, "TIME|%.3f\n", TimeUsed); |
| exit(0); |
| #endif |
| } |
| |
| 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; 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 = 1.0 - t; |
| } |
| t = t0; |
| } |
| timeb = (dtime()-timea)/(SPDP)(n1mult); |
| pout("N1 floating point\0",(float)(n1*16)*(float)(xtra), |
| 1,e1[3],timeb,calibrate,1); |
| |
| /* Section 2, Array as parameter */ |
| |
| timea = dtime(); |
| { |
| for (ix=0; ix<xtra; ix++) |
| { |
| for(i=0; i<n2; i++) |
| { |
| pa(e1,t,t2); |
| } |
| t = 1.0 - t; |
| } |
| t = t0; |
| } |
| timeb = dtime()-timea; |
| pout("N2 floating point\0",(float)(n2*96)*(float)(xtra), |
| 1,e1[3],timeb,calibrate,2); |
| |
| /* Section 3, Conditional jumps */ |
| j = 1; |
| timea = dtime(); |
| { |
| 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; |
| } |
| } |
| } |
| 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; 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] = j + k + l; |
| e1[k-2] = j * k * l; |
| } |
| } |
| } |
| timeb = dtime()-timea; |
| x = e1[0]+e1[1]; |
| pout("N4 fixed point \0",(float)(n4*15)*(float)(xtra), |
| 2,x,timeb,calibrate,4); |
| |
| /* Section 5, Trig functions */ |
| x = 0.5; |
| y = 0.5; |
| timea = dtime(); |
| { |
| for (ix=0; ix<xtra; ix++) |
| { |
| for(i=1; i<n5; i++) |
| { |
| x = t*atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0)); |
| y = t*atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0)); |
| } |
| t = 1.0 - t; |
| } |
| t = t0; |
| } |
| timeb = dtime()-timea; |
| pout("N5 sin,cos etc. \0",(float)(n5*26)*(float)(xtra), |
| 2,y,timeb,calibrate,5); |
| |
| /* Section 6, Procedure calls */ |
| x = 1.0; |
| y = 1.0; |
| z = 1.0; |
| timea = dtime(); |
| { |
| for (ix=0; ix<xtra; ix++) |
| { |
| for(i=0; i<n6; i++) |
| { |
| p3(&x,&y,&z,t,t1,t2); |
| } |
| } |
| } |
| timeb = dtime()-timea; |
| pout("N6 floating point\0",(float)(n6*6)*(float)(xtra), |
| 1,z,timeb,calibrate,6); |
| |
| /* Section 7, Array refrences */ |
| j = 0; |
| k = 1; |
| l = 2; |
| e1[0] = 1.0; |
| e1[1] = 2.0; |
| e1[2] = 3.0; |
| timea = dtime(); |
| { |
| for (ix=0; ix<xtra; ix++) |
| { |
| for(i=0;i<n7;i++) |
| { |
| po(e1,j,k,l); |
| } |
| } |
| } |
| timeb = dtime()-timea; |
| pout("N7 assignments \0",(float)(n7*3)*(float)(xtra), |
| 2,e1[2],timeb,calibrate,7); |
| |
| /* Section 8, Standard functions */ |
| x = 0.75; |
| timea = dtime(); |
| { |
| for (ix=0; ix<xtra; ix++) |
| { |
| for(i=0; i<n8; i++) |
| { |
| x = sqrt(exp(log(x)/t1)); |
| } |
| } |
| } |
| timeb = dtime()-timea; |
| pout("N8 exp,sqrt etc. \0",(float)(n8*4)*(float)(xtra), |
| 2,x,timeb,calibrate,8); |
| |
| 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 pout(char title[18], float ops, int type, SPDP checknum, |
| SPDP time, int calibrate, int section) |
| { |
| SPDP mops,mflops; |
| |
| Check = Check + checknum; |
| loop_time[section] = time; |
| strcpy (headings[section],title); |
| TimeUsed = TimeUsed + time; |
| if (calibrate == 1) |
| |
| { |
| results[section] = checknum; |
| } |
| if (calibrate == 0) |
| { |
| printf("%s %24.17f ",headings[section],results[section]); |
| |
| if (type == 1) |
| { |
| if (time>0) |
| { |
| 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 <ctype.h> |
| #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 <sys/time.h> |
| #include <sys/resource.h> |
| |
| #ifdef hpux |
| #include <sys/syscall.h> |
| #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 <sys/types.h> |
| #include <sys/times.h> |
| #include <sys/param.h> |
| |
| #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 <ctype.h> |
| #include <dos.h> |
| #include <time.h> |
| |
| #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 <time.h> |
| #include <ctype.h> |
| |
| #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 <time.h> |
| |
| #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 <time.h> |
| |
| 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 <sys/time.h> |
| |
| 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 <sys/types.h> |
| #include <sys/timesu.h> |
| 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 <MacHeaders> in the prefix */ |
| /* provided by Francis H Schiffer 3rd (fhs) */ |
| /* skipschiffer@genie.geis.com */ |
| /**********************************************/ |
| #ifdef MAC_TMgr |
| #include <Timer.h> |
| #include <stdlib.h> |
| |
| 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 <sys/time.h> |
| |
| 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 <sys/time.h> |
| #include <sys/resource.h> |
| #include <sys/rusage.h> |
| |
| #ifdef __hpux |
| #include <sys/syscall.h> |
| #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 <windows.h> |
| |
| SPDP dtime(void) |
| { |
| SPDP q; |
| |
| q = (SPDP)GetTickCount() * 1.0e-03; |
| |
| return q; |
| } |
| #endif |
| |
| /*****************************************************/ |
| /* Time according to POSIX.1 - <J.Pelan@qub.ac.uk> */ |
| /* Ref: "POSIX Programmer's Guide" O'Reilly & Assoc.*/ |
| /*****************************************************/ |
| #ifdef POSIX1 |
| #define _POSIX_SOURCE 1 |
| #include <unistd.h> |
| #include <limits.h> |
| #include <sys/times.h> |
| |
| struct tms tms; |
| |
| SPDP dtime() |
| { |
| SPDP q; |
| times(&tms); |
| q = (SPDP)tms.tms_utime / (SPDP)CLK_TCK; |
| return q; |
| } |
| #endif |