~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/whets.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-06-11 15:45:24 UTC
  • mfrom: (1.2.1) (2.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130611154524-rppb3w6tixlegv4n
Tags: 1.4.7~20130611~a1eb425-1
* New snapshot release
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  gcc whets.c cpuidc64.o cpuida64.o -m64 -lrt -lc -lm -o whet
 
2
*
 
3
*  XXX modified by emscripten to be slower, to not slow down test runner
 
4
*
 
5
*  Document:         Whets.c 
 
6
*  File Group:       Classic Benchmarks
 
7
*  Creation Date:    6 November 1996
 
8
*  Revision Date:    6 November 2010 Ubuntu Version for PCs
 
9
*
 
10
*  Title:            Whetstone Benchmark in C/C++
 
11
*  Keywords:         WHETSTONE BENCHMARK PERFORMANCE MIPS
 
12
*                    MWIPS MFLOPS
 
13
*
 
14
*  Abstract:         C or C++ version of Whetstone one of the
 
15
*                    Classic Numeric Benchmarks with example
 
16
*                    results on P3 to P6 based PCs.        
 
17
*
 
18
*  Contributor:      roy@roylongbottom.org.uk
 
19
*
 
20
************************************************************
 
21
*
 
22
*     C/C++ Whetstone Benchmark Single or Double Precision
 
23
*
 
24
*     Original concept        Brian Wichmann NPL      1960's
 
25
*     Original author         Harold Curnow  CCTA     1972
 
26
*     Self timing versions    Roy Longbottom CCTA     1978/87
 
27
*     Optimisation control    Bangor University       1987/90
 
28
*     C/C++ Version           Roy Longbottom          1996
 
29
*     Compatibility & timers  Al Aburto               1996
 
30
*
 
31
************************************************************
 
32
*
 
33
*              Official version approved by:
 
34
*
 
35
*         Harold Curnow  100421.1615@compuserve.com
 
36
*
 
37
*      Happy 25th birthday Whetstone, 21 November 1997
 
38
*
 
39
************************************************************
 
40
*
 
41
*     The program normally runs for about 100 seconds
 
42
*     (adjustable in main - variable duration). This time
 
43
*     is necessary because of poor PC clock resolution.
 
44
*     The original concept included such things as a given
 
45
*     number of subroutine calls and divides which may be
 
46
*     changed by optimisation. For comparison purposes the
 
47
*     compiler and level of optimisation should be identified.
 
48
*
 
49
*     This version is set to run for 10 seconds using high
 
50
*     resolution timer.
 
51
*       
 
52
************************************************************
 
53
*
 
54
*     The original benchmark had a single variable I which
 
55
*     controlled the running time. Constants with values up
 
56
*     to 899 were multiplied by I to control the number
 
57
*     passes for each loop. It was found that large values
 
58
*     of I could overflow index registers so an extra outer
 
59
*     loop with a second variable J was added.
 
60
*
 
61
*     Self timing versions were produced during the early
 
62
*     days. The 1978 changes supplied timings of individual
 
63
*     loops and these were used later to produce MFLOPS and
 
64
*     MOPS ratings.
 
65
*
 
66
*     1987 changes converted the benchmark to Fortran 77
 
67
*     standards and removed redundant IF statements and
 
68
*     loops to leave the 8 active loops N1 to N8. Procedure
 
69
*     P3 was changed to use global variables to avoid over-
 
70
*     optimisation with the first two statements changed from
 
71
*     X1=X and Y1=Y to X=Y and Y=Z. A self time calibrating
 
72
*     version for PCs was also produced, the facility being
 
73
*     incorporated in this version.
 
74
*
 
75
*     This version has changes to avoid worse than expected
 
76
*     speed ratings, due to underflow, and facilities to show
 
77
*     that consistent numeric output is produced with varying
 
78
*     optimisation levels or versions in different languages.
 
79
*
 
80
*     Some of the procedures produce ever decreasing numbers.
 
81
*     To avoid problems, variables T and T1 have been changed
 
82
*     from 0.499975 and 0.50025 to 0.49999975 and 0.50000025.
 
83
*
 
84
*     Each section now has its own double loop. Inner loops
 
85
*     are run 100 times the loop constants. Calibration
 
86
*     determines the number of outer loop passes. The
 
87
*     numeric results produced in the main output are for
 
88
*     one pass on the outer loop. As underflow problems were
 
89
*     still likely on a processor 100 times faster than a 100
 
90
*     MHz Pentium, three sections have T=1.0-T inserted in the
 
91
*     outer loop to avoid the problem. The two loops avoid
 
92
*     index register overflows.
 
93
*
 
94
*     The first section is run ten times longer than required
 
95
*     for accuracy in calculating MFLOPS. This time is divided
 
96
*     by ten for inclusion in the MWIPS calculations.
 
97
*
 
98
*     Early version has facilities for typing in details of
 
99
*     the particular run, appended to file whets.txt along
 
100
*     with the results. This version attemps to obtain these
 
101
*     automatically.
 
102
*
 
103
*     2010 Section 4 modified slightly to avoid over optimisation
 
104
*     by GCC compiler
 
105
*
 
106
*     Roy Longbottom  roy@roylongbottom.org.uk
 
107
*
 
108
************************************************************
 
109
*
 
110
*     Whetstone benchmark results, further details of the
 
111
*     benchmarks and history are available from:
 
112
*
 
113
*     http://www.roylongbottom.org.uk/whetstone%20results.htm
 
114
*     http://www.roylongbottom.org.uk/whetstone.htm
 
115
*
 
116
************************************************************
 
117
*
 
118
*     Source code is available in C/C++, Fortran, Basic and
 
119
*     Visual Basic in the same format as this version. Pre-
 
120
*     compiled versions for PCs are also available via C++.
 
121
*     These comprise optimised and non-optimised versions
 
122
*     for DOS, Windows and NT. See:
 
123
*
 
124
*     http://www.roylongbottom.org.uk/whetstone%20results.htm
 
125
*
 
126
************************************************************
 
127
*
 
128
* Example of initial calibration display (Pentium 100 MHz)
 
129
*
 
130
* Single Precision C/C++ Whetstone Benchmark
 
131
*
 
132
* Calibrate
 
133
*      0.17 Seconds          1   Passes (x 100)
 
134
*      0.77 Seconds          5   Passes (x 100)
 
135
*      3.70 Seconds         25   Passes (x 100)
 
136
*
 
137
* Use 676  passes (x 100)
 
138
*
 
139
* 676 passes are used for an approximate duration of 100
 
140
* seconds, providing an initial estimate of a speed rating
 
141
* of 67.6 MWIPS.
 
142
*
 
143
* This is followed by the table of results as below.
 
144
 
 
145
* Whetstone Single  Precision Benchmark in C/C++
 
146
*
 
147
* Loop content                 Result            MFLOPS     MOPS   Seconds
 
148
*
 
149
* N1 floating point    -1.12475025653839100      19.971              0.274
 
150
* N2 floating point    -1.12274754047393800      11.822              3.240
 
151
* N3 if then else       1.00000000000000000               11.659     2.530
 
152
* N4 fixed point       12.00000000000000000               13.962     6.430
 
153
* N5 sin,cos etc.       0.49904659390449520                2.097    11.310
 
154
* N6 floating point     0.99999988079071040       3.360             45.750
 
155
* N7 assignments        3.00000000000000000                2.415    21.810
 
156
* N8 exp,sqrt etc.      0.75110864639282230                1.206     8.790
 
157
*
 
158
* MWIPS                                          28.462            100.134
 
159
*
 
160
*  Note different numeric results to single precision. Slight variations
 
161
*  are normal with different compilers and sometimes optimisation levels. 
 
162
*
 
163
**************************************************************************/
 
164
 
 
165
#define _CRT_SECURE_NO_WARNINGS 1
 
166
#ifdef WIN32
 
167
#include <Windows.h>
 
168
#else
 
169
#include <sys/time.h>
 
170
#endif
 
171
 
 
172
#include <math.h>       /* for sin, exp etc.           */
 
173
#include <stdio.h>      /* standard I/O                */ 
 
174
#include <string.h>     /* for strcpy - 3 occurrences  */
 
175
#include <stdlib.h>     /* for exit   - 1 occurrence   */
 
176
#include <time.h> 
 
177
 
 
178
/*  #include "cpuidh.h" */
 
179
 
 
180
/*PRECISION PRECISION PRECISION PRECISION PRECISION PRECISION PRECISION*/
 
181
 
 
182
/* #define DP */
 
183
 
 
184
#ifdef DP 
 
185
#define SPDP double
 
186
#define Precision "Double"
 
187
#else
 
188
#define SPDP float
 
189
#define Precision "Single"
 
190
#endif
 
191
 
 
192
#define opt "Opt 3 64 Bit"
 
193
 
 
194
void whetstones(long xtra, long x100, int calibrate);  
 
195
void pa(SPDP e[4], SPDP t, SPDP t2);
 
196
void po(SPDP e1[4], long j, long k, long l);
 
197
void p3(SPDP *x, SPDP *y, SPDP *z, SPDP t, SPDP t1, SPDP t2);
 
198
void pout(char title[22], float ops, int type, SPDP checknum,
 
199
          SPDP time, int calibrate, int section);
 
200
 
 
201
 
 
202
static SPDP loop_time[9];
 
203
static SPDP loop_mops[9];
 
204
static SPDP loop_mflops[9];
 
205
static SPDP TimeUsed;
 
206
static SPDP mwips;
 
207
static char headings[9][18];
 
208
static SPDP Check;
 
209
static SPDP results[9];
 
210
 
 
211
/* this is truly rank, but it's minimally invasive, and lifted in part from the STREAM scores */
 
212
 
 
213
static double secs;
 
214
 
 
215
#ifndef WIN32
 
216
 
 
217
double mysecond()
 
218
{
 
219
        struct timeval tp;
 
220
        struct timezone tzp;
 
221
        int i;
 
222
 
 
223
        i = gettimeofday(&tp,&tzp);
 
224
        return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
 
225
}
 
226
#else
 
227
 
 
228
double mysecond()
 
229
{
 
230
        static LARGE_INTEGER freq = {0};
 
231
        LARGE_INTEGER count = {0};
 
232
        if(freq.QuadPart == 0LL) {
 
233
                QueryPerformanceFrequency(&freq);
 
234
        }
 
235
        QueryPerformanceCounter(&count);
 
236
        return (double)count.QuadPart / (double)freq.QuadPart;
 
237
}
 
238
 
 
239
#endif
 
240
 
 
241
void start_time()
 
242
{
 
243
        secs = mysecond();
 
244
}
 
245
 
 
246
void end_time()
 
247
{
 
248
        secs = mysecond() - secs;
 
249
}
 
250
 
 
251
int main(int argc, char *argv[])
 
252
{
 
253
        int count = 1, calibrate = 1;
 
254
        long xtra = 1;
 
255
        int section;
 
256
        long x100 = 1;
 
257
        int duration = 1;
 
258
        char compiler[80], options[256], general[10][80] = {" "};
 
259
        char endit[80];
 
260
        int i;
 
261
 
 
262
        printf("\n");
 
263
        printf("##########################################\n");
 
264
        {
 
265
                time_t t;
 
266
                char timeday[30];
 
267
                t = time(NULL);
 
268
                sprintf(timeday, "%s", asctime(localtime(&t)));
 
269
 
 
270
                printf("%s Precision C Whetstone Benchmark %s, %s\n", Precision, opt, timeday);
 
271
        }
 
272
 
 
273
        printf("Calibrate\n");
 
274
        do
 
275
        {
 
276
                TimeUsed=0;
 
277
 
 
278
                whetstones(xtra,x100,calibrate);
 
279
 
 
280
                printf("%11.2f Seconds %10.0lf   Passes (x 100)\n",
 
281
                        TimeUsed,(SPDP)(xtra));
 
282
                calibrate++;
 
283
                count--;
 
284
 
 
285
                if (TimeUsed > 2.0)
 
286
                {
 
287
                        count = 0;
 
288
                }
 
289
                else
 
290
                {
 
291
                        xtra = xtra * 5;
 
292
                }
 
293
        }
 
294
 
 
295
        while (count > 0);
 
296
 
 
297
        if (TimeUsed > 0) xtra = (long)((SPDP)(duration * xtra) / TimeUsed);
 
298
        if (xtra < 1) xtra = 1;
 
299
 
 
300
        calibrate = 0;
 
301
 
 
302
        printf("\nUse %d  passes (x 100)\n", (int)xtra);
 
303
 
 
304
        printf("\n          %s Precision C/C++ Whetstone Benchmark",Precision);
 
305
 
 
306
#ifdef PRECOMP
 
307
        printf("\n          Compiler  %s", precompiler);
 
308
        printf("\n          Options   %s\n", preoptions);
 
309
#else
 
310
        printf("\n");
 
311
#endif
 
312
 
 
313
        printf("\nLoop content                  Result              MFLOPS "
 
314
                "     MOPS   Seconds\n\n");
 
315
 
 
316
        TimeUsed=0;
 
317
        whetstones(xtra,x100,calibrate);
 
318
 
 
319
        printf("\nMWIPS            ");
 
320
        if (TimeUsed>0)
 
321
        {
 
322
                mwips=(float)(xtra) * (float)(x100) / (10 * TimeUsed);
 
323
        }
 
324
        else
 
325
        {
 
326
                mwips = 0;
 
327
        }  
 
328
 
 
329
        printf("%39.3f%19.3f\n\n",mwips,TimeUsed);
 
330
 
 
331
        if (Check == 0) printf("Wrong answer  ");
 
332
 
 
333
        printf ("\n");
 
334
        printf ("A new results file, whets.txt,  will have been created in the same\n");
 
335
        printf ("directory as the .EXE files, if one did not already exist.\n\n");
 
336
 
 
337
        return 0;             
 
338
}
 
339
 
 
340
void whetstones(long xtra, long x100, int calibrate)
 
341
{
 
342
 
 
343
        long n1,n2,n3,n4,n5,n6,n7,n8,i,ix,n1mult;
 
344
        SPDP x,y,z;              
 
345
        long j,k,l;
 
346
        SPDP e1[4];
 
347
 
 
348
        SPDP t =  0.49999975;
 
349
        SPDP t0 = t;        
 
350
        SPDP t1 = 0.50000025;
 
351
        SPDP t2 = 2.0;
 
352
 
 
353
        Check=0.0;
 
354
 
 
355
        n1 = 1*x100;
 
356
        n2 = 1*x100;
 
357
        n3 = 3*x100;
 
358
        n4 = 2*x100;
 
359
        n5 = 3*x100;
 
360
        n6 = 8*x100;
 
361
        n7 = 6*x100;
 
362
        n8 = 9*x100;
 
363
        n1mult = 1;
 
364
 
 
365
        /* Section 1, Array elements */
 
366
 
 
367
        e1[0] = 1.0;
 
368
        e1[1] = -1.0;
 
369
        e1[2] = -1.0;
 
370
        e1[3] = -1.0;
 
371
        start_time();
 
372
        {
 
373
                for (ix=0; ix<xtra; ix++)
 
374
                {
 
375
                        for(i=0; i<n1*n1mult; i++)
 
376
                        {
 
377
                                e1[0] = (e1[0] + e1[1] + e1[2] - e1[3]) * t;
 
378
                                e1[1] = (e1[0] + e1[1] - e1[2] + e1[3]) * t;
 
379
                                e1[2] = (e1[0] - e1[1] + e1[2] + e1[3]) * t;
 
380
                                e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3]) * t;
 
381
                        }
 
382
                        t = 1.0 - t;
 
383
                }
 
384
                t =  t0;                    
 
385
        }
 
386
        end_time();
 
387
        secs = secs/(SPDP)(n1mult);
 
388
        pout("N1 floating point\0",(float)(n1*16)*(float)(xtra),
 
389
                1,e1[3],secs,calibrate,1);
 
390
 
 
391
        /* Section 2, Array as parameter */
 
392
 
 
393
        start_time();
 
394
        {
 
395
                for (ix=0; ix<xtra; ix++)
 
396
                { 
 
397
                        for(i=0; i<n2; i++)
 
398
                        {
 
399
                                pa(e1,t,t2);
 
400
                        }
 
401
                        t = 1.0 - t;
 
402
                }
 
403
                t =  t0;
 
404
        }
 
405
        end_time();
 
406
        pout("N2 floating point\0",(float)(n2*96)*(float)(xtra),
 
407
                1,e1[3],secs,calibrate,2);
 
408
 
 
409
        /* Section 3, Conditional jumps */
 
410
        j = 1;
 
411
        start_time();
 
412
        {
 
413
                for (ix=0; ix<xtra; ix++)
 
414
                {
 
415
                        for(i=0; i<n3; i++)
 
416
                        {
 
417
                                if(j==1)       j = 2;
 
418
                                else           j = 3;
 
419
                                if(j>2)        j = 0;
 
420
                                else           j = 1;
 
421
                                if(j<1)        j = 1;
 
422
                                else           j = 0;
 
423
                        }
 
424
                }
 
425
        }
 
426
        end_time();
 
427
        pout("N3 if then else  \0",(float)(n3*3)*(float)(xtra),
 
428
                2,(SPDP)(j),secs,calibrate,3);
 
429
 
 
430
        /* Section 4, Integer arithmetic */
 
431
        j = 1;
 
432
        k = 2;
 
433
        l = 3;
 
434
        e1[0] = 0.0;
 
435
        e1[1] = 0.0;
 
436
        start_time();
 
437
        {
 
438
                for (ix=0; ix<xtra; ix++)
 
439
                {
 
440
                        for(i=0; i<n4; i++)
 
441
                        {
 
442
                                j = j *(k-j)*(l-k);
 
443
                                k = l * k - (l-j) * k;
 
444
                                l = (l-k) * (k+j);
 
445
                                e1[l-2] = e1[l-2] + j + k + l;
 
446
                                e1[k-2] = e1[k-2] + j * k * l;
 
447
                                //  was          e1[l-2] = j + k + l; and  e1[k-2] = j * k * l;
 
448
                        }
 
449
                }
 
450
        }
 
451
        end_time();
 
452
        x = (e1[0]+e1[1])/(SPDP)n4/(SPDP)xtra;   // was x = e1[0]+e1[1];
 
453
        pout("N4 fixed point   \0",(float)(n4*15)*(float)(xtra),
 
454
                2,x,secs,calibrate,4);
 
455
 
 
456
        /* Section 5, Trig functions */
 
457
        x = 0.5;
 
458
        y = 0.5;
 
459
        start_time();
 
460
        {
 
461
                for (ix=0; ix<xtra; ix++)
 
462
                {
 
463
                        for(i=1; i<n5; i++)
 
464
                        {
 
465
                                x = t*atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0));
 
466
                                y = t*atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0));
 
467
                        }
 
468
                        t = 1.0 - t;
 
469
                }
 
470
                t = t0;
 
471
        }
 
472
        end_time();
 
473
        pout("N5 sin,cos etc.  \0",(float)(n5*26)*(float)(xtra),
 
474
                2,y,secs,calibrate,5);
 
475
 
 
476
 
 
477
        /* Section 6, Procedure calls */
 
478
        x = 1.0;
 
479
 
 
480
        y = 1.0;
 
481
        z = 1.0;
 
482
        start_time();
 
483
        {
 
484
                for (ix=0; ix<xtra; ix++)
 
485
                {
 
486
                        for(i=0; i<n6; i++)
 
487
                        {
 
488
                                p3(&x,&y,&z,t,t1,t2);
 
489
                        }
 
490
                }
 
491
        }
 
492
        end_time();
 
493
        pout("N6 floating point\0",(float)(n6*6)*(float)(xtra),
 
494
                1,z,secs,calibrate,6);
 
495
 
 
496
        /* Section 7, Array refrences */
 
497
        j = 0;
 
498
        k = 1;
 
499
        l = 2;
 
500
        e1[0] = 1.0;
 
501
        e1[1] = 2.0;
 
502
        e1[2] = 3.0;
 
503
        start_time();
 
504
        {
 
505
                for (ix=0; ix<xtra; ix++)
 
506
                {
 
507
                        for(i=0;i<n7;i++)
 
508
                        {
 
509
                                po(e1,j,k,l);
 
510
                        }
 
511
                }
 
512
        }
 
513
        end_time();
 
514
        pout("N7 assignments   \0",(float)(n7*3)*(float)(xtra),
 
515
                2,e1[2],secs,calibrate,7);
 
516
 
 
517
        /* Section 8, Standard functions */
 
518
        x = 0.75;
 
519
        start_time();
 
520
        {
 
521
                for (ix=0; ix<xtra; ix++)
 
522
                {
 
523
                        for(i=0; i<n8; i++)
 
524
                        {
 
525
                                x = sqrt(exp(log(x)/t1));
 
526
                        }
 
527
                }
 
528
        }
 
529
        end_time();
 
530
        pout("N8 exp,sqrt etc. \0",(float)(n8*4)*(float)(xtra),
 
531
                2,x,secs,calibrate,8);
 
532
 
 
533
        return;
 
534
}
 
535
 
 
536
 
 
537
void pa(SPDP e[4], SPDP t, SPDP t2)
 
538
{
 
539
        long j;
 
540
        for(j=0;j<6;j++)
 
541
        {
 
542
                e[0] = (e[0]+e[1]+e[2]-e[3])*t;
 
543
                e[1] = (e[0]+e[1]-e[2]+e[3])*t;
 
544
                e[2] = (e[0]-e[1]+e[2]+e[3])*t;
 
545
                e[3] = (-e[0]+e[1]+e[2]+e[3])/t2;
 
546
        }
 
547
 
 
548
        return;
 
549
}
 
550
 
 
551
void po(SPDP e1[4], long j, long k, long l)
 
552
{
 
553
        e1[j] = e1[k];
 
554
        e1[k] = e1[l];
 
555
        e1[l] = e1[j];
 
556
        return;
 
557
}
 
558
 
 
559
void p3(SPDP *x, SPDP *y, SPDP *z, SPDP t, SPDP t1, SPDP t2)
 
560
{
 
561
        *x = *y;
 
562
        *y = *z;
 
563
        *x = t * (*x + *y);
 
564
        *y = t1 * (*x + *y);
 
565
        *z = (*x + *y)/t2;
 
566
        return;
 
567
}
 
568
 
 
569
 
 
570
void pout(char title[18], float ops, int type, SPDP checknum,
 
571
                  SPDP time, int calibrate, int section)
 
572
{
 
573
        SPDP mops,mflops;
 
574
 
 
575
        Check = Check + checknum;
 
576
        loop_time[section] = time;
 
577
        strcpy (headings[section],title);
 
578
        TimeUsed =  TimeUsed + time;
 
579
        if (calibrate == 1)
 
580
 
 
581
        {
 
582
                results[section] = checknum;
 
583
        }
 
584
        if (calibrate == 0)
 
585
        {              
 
586
                printf("%s %24.17f    ",headings[section],results[section]);    
 
587
 
 
588
                if (type == 1)
 
589
                {
 
590
                        if (time>0)
 
591
                        {
 
592
                                mflops = ops/(1000000L*time);
 
593
                        }
 
594
                        else
 
595
                        {
 
596
                                mflops = 0;
 
597
                        }
 
598
                        loop_mops[section] = 99999;
 
599
                        loop_mflops[section] = mflops;
 
600
                        printf(" %9.3f          %9.3f\n",
 
601
                                loop_mflops[section], loop_time[section]);                
 
602
                }
 
603
                else
 
604
                {
 
605
                        if (time>0)
 
606
                        {
 
607
                                mops = ops/(1000000L*time);
 
608
                        }
 
609
                        else
 
610
                        {
 
611
                                mops = 0;
 
612
                        }
 
613
                        loop_mops[section] = mops;
 
614
                        loop_mflops[section] = 0;                 
 
615
                        printf("           %9.3f%9.3f\n",
 
616
                                loop_mops[section], loop_time[section]);
 
617
                }
 
618
        }
 
619
 
 
620
        return;
 
621
}
 
622