home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / BENCHMARKS / flops.c < prev    next >
C/C++ Source or Header  |  2009-11-06  |  14KB  |  507 lines

  1. /*****************************/
  2. /*          FLOPS.c          */
  3. /*  Version 1.2, 29 Feb 1992 */
  4. /*         Al Aburto         */
  5. /*      'ala' on BIX         */
  6. /*  aburto@marlin.nosc.mil   */
  7. /*****************************/
  8.  
  9. /*
  10.    FLOPS.c is a 'c' program which attempts to estimate your systems scalar
  11.    floating-point 'MFLOP' rating for the scalar +, -, *, and / operations
  12.    based on a specific 'instruction mix'. It attempts to measure the time
  13.    for an FADD and the time to do an empty 'for' loop in microseconds. It
  14.    calculates pi based on the series expansion for atan(1.0). A few
  15.    correction terms are applied to achieve at most a 16 digit accurate
  16.    result. It calculates the area under the sin(x) curve from 0 to pi/3
  17.    using the Trapazoidal rule. Sin(x) is approximated by a polynomial
  18.    series accurate to approximately 1.0e-14 over the specified range. The
  19.    program is designed for double precision. The program does not work
  20.    with arrays and thus it is not an appropriate program for an important
  21.    group of processors (array, vector, and possibly other type machines).
  22.    It gives a Scalar (one dimensional) MFLOP rating, not an N-Scalar or
  23.    vector MFLOP rating. It was originally intended for PC's but it is
  24.    applicable for a wide variety of different machines.
  25.  
  26.    The Scalar MFLOPS rating is based on a count of 52 total scalar
  27.    floating-point operations per loop (iteration). The instruction mix is:
  28.    FADD: 40.38, FSUB: 23.31, FMUL: 26.92, and FDIV: 9.62 percent. This is
  29.    based on instruction mix data found in the Dhrystone paper by Reinhold
  30.    P. Weicker, Communications of the ACM, Oct 1984, Vol 27, Number 10,
  31.    Page 1013 (Table IV). This is the best available information I found in
  32.    which to base the instruction mix.
  33.  
  34.    Version 1.2 corrects some problems encountered with Version 1.1. A timer
  35.    routine for UNIX using 'getrusage()' has been added by Markku Kolkka of
  36.    Tampere University of Technology, Finland. This eliminates problems with
  37.    the definition of 'HZ' in the old routine (UNIX_Old). I eliminated the
  38.    'w' sum in the second loop as it did nothing. The FADD time is now
  39.    estimated (the printf is commented out, but you can uncomment it to see
  40.    what it says) and I use it solely to estimate the number of loops to
  41.    conduct: 20 million loops when the program estimates the FADD is faster
  42.    than 1/3 usec, 0.1 million loops for FADD slower than 4 usec, and
  43.    1 million loops otherwise. If the number of loops conducted is not
  44.    properly related to 'loops' then the program prints out a message saying
  45.    the program and results are invalid. Bo Thide' of the Swedish Institute
  46.    of Space Physics, Sweden caught an error in the value for 'piref' and
  47.    that has been corrected. The time to do an empty 'for' loop is also 
  48.    estimated somewhat better since there are now automatic longer loops.
  49.  
  50.    The V1.2 results are not expected to show any significant difference
  51.    relative to the V1.1 results. I verified this with several machines
  52.    running in the 1 to 6 MFLOP range, but you might want to recheck the
  53.    faster machines. The results do vary even when doing 20 million loops.
  54.    The maximum standard deviation I observed in the systems I checked was
  55.    0.07 MFLOP at the 6 MFLOP range.
  56.  
  57.    See the next page for 'register' and 'timer' options available in the
  58.    program. Example UNIX compilation is: 'cc -DUNIX -O2 flops.c -o flops',
  59.    or 'cc -DUNIX -DROPT flops.c -o flops', ... , etc.
  60.  
  61.    NOTE: Please do not remove any of the printouts.
  62.  
  63.    Al Aburto
  64. */
  65.  
  66. #include <stdio.h>
  67. #include <math.h>
  68.                  /* 'Uncomment' the line below to run   */
  69.                  /* with 'register double' variables    */
  70.                  /* defined, or compile with the        */
  71.                  /* '-DROPT' option. Don't need this if */
  72.                  /* registers used automatically.       */
  73. /* #define ROPT */
  74.                  /* 'Uncomment' one of the statements   */
  75.                  /* below to access the right timer     */
  76.                  /* routine for your system, or compile */
  77.                  /* with '-DUNIX' (for example). You    */
  78.                  /* may need to write your own similar  */
  79.                  /* timer routine if you have another   */
  80.                  /* system or compiler not covered by   */
  81.                  /* the options below. I have not tested*/
  82.                  /* the 'MSC' option.                   */
  83. /* #define Amiga    */
  84. /* #define UNIX     */
  85. /* #define UNIX_Old */
  86. /* #define TURBO_C  */
  87. /* #define MSC      */
  88.  
  89.  
  90. #ifdef Amiga
  91. #include <ctype.h>
  92. #define HZ   50
  93. #endif
  94.  
  95. #ifdef _OSK
  96. #include <time.h>
  97. clock_t  tnow;
  98. #endif
  99.  
  100. #ifdef UNIX
  101. #include <sys/time.h>
  102. #include <sys/resource.h>
  103. struct rusage rusage;
  104. #endif
  105.  
  106. #ifdef UNIX_Old
  107. #include <sys/types.h>
  108. #include <sys/times.h>
  109. #include <sys/param.h>
  110. #ifndef HZ
  111. #define HZ   60
  112. #endif
  113. struct tms tms;
  114. #endif
  115.  
  116. #ifdef TURBO_C
  117. #include <ctype.h>
  118. #include <dos.h>
  119. #include <time.h>
  120. #define HZ   100
  121. struct time now;
  122. #endif
  123.  
  124. #ifdef MSC
  125. #include <time.h>
  126. #include <ctype.h>
  127. #define HZ   CLK_TCK
  128. clock_t  tnow;
  129. #endif
  130.  
  131.  
  132. double TimeArray[3];             /* Time Array needed for 'dtime()'.    */
  133.  
  134. double T[25];                    /* Global Array used to hold timing    */
  135.                  /* results and other information.      */
  136.  
  137. double sa,sb,sc,sd,one,two,three;
  138. double four,five,piref,piprg;
  139. double pierr,delta;
  140.  
  141. double A0 = 1.0;
  142. double A1 =-0.1666666666671334;
  143. double A2 = 0.833333333809067E-2;
  144. double A3 = 0.198412715551283E-3;
  145. double A4 = 0.27557589750762E-5;
  146. double A5 = 0.2507059876207E-7;
  147. double A6 = 0.164105986683E-9;
  148.  
  149.  
  150.  
  151. void main()
  152. {
  153.  
  154. #ifdef ROPT
  155.    register double s,u,v,w,x;
  156. #else
  157.    double s,u,v,w,x;
  158. #endif
  159.  
  160.    long  i, loops, m, n;
  161.  
  162.    printf("\n");
  163.    printf("   FLOPS C Program (Double Precision)\n");
  164.    printf("       Version 1.2, 29 Feb 1992\n\n");
  165.  
  166.                  /******************************/
  167.    loops = 1000000;          /* Number of loops conducted. */
  168.                  /******************************/
  169.  
  170. /****************************************************/
  171. /* Set Global Variable Values.  T[24] References    */
  172. /* All Timing Results Relative To 1 Million Loops.  */
  173. /****************************************************/
  174.  
  175.    T[24] = 1.0e+06/(double)loops;
  176.  
  177.    piref = 3.14159265358979324;
  178.    one  = 1.0;
  179.    two  = 2.0;
  180.    three= 3.0;
  181.    four = 4.0;
  182.    five = 5.0;
  183.      sd = one;
  184.  
  185. /**********************************/
  186. /* Module 1.  Estimate Loop time  */
  187. /*            and FADD time.      */
  188. /**********************************/
  189.  
  190.    u = 0.0;                                        /*********************/
  191.    v = one;                                        /* Loop 1.           */
  192.                            /*********************/
  193.    dtime(TimeArray);
  194.    for( i = 1 ; i<= loops ; i++ )
  195.    {
  196.    u = u + v;
  197.    }
  198.    dtime(TimeArray);
  199.    T[19] = T[24] * TimeArray[1];
  200.    m = (long)u;
  201.                            /*********************/
  202.    u = 0.0;                                        /* Loop 2.           */
  203.    s = 0.0;                                        /*********************/
  204.  
  205.    dtime(TimeArray);
  206.    for( i = 1 ; i<= m ; i++ )
  207.    {
  208.    u = u + v;
  209.    s = s + u;
  210.    }
  211.    dtime(TimeArray);
  212.    T[20] = T[24] * TimeArray[1];
  213.                            /********************/
  214.    T[21] = two * T[19] - T[20];                    /* Loop Time (usec) */
  215.    if ( T[21] < 0.0 ) T[21] = 0.0;                 /* First Estimate.  */
  216.                            /********************/
  217.    n = (long)( two * ( s / u ) - one );
  218.                            /********************/
  219.    T[22] = T[20] - T[19];                          /* FADD Time (usec) */
  220.    if ( T[22] < 0.0 ) T[22] = 0.0;                 /* First Estimate.  */
  221.                            /********************/
  222.    m = n;
  223.  
  224.    if ( T[22] < (one / three) )
  225.    {
  226.    sd    = one / 20.0;
  227.    m     = 20 * n;
  228.    T[24] = 1.0e+06/(double)m;
  229.    }
  230.  
  231.    if ( T[22] > four )
  232.    {
  233.    sd    = 10.0;
  234.    m     = n / 10;
  235.    T[24] = 1.0e+06/(double)m;
  236.    }
  237.  
  238.                            /*********************/
  239.    u = 0.0;                                        /* Loop 3.           */
  240.                            /*********************/
  241.    dtime(TimeArray);
  242.    for( i = 1 ; i<= m ; i++ )
  243.    {
  244.    u = u + v;
  245.    }
  246.    dtime(TimeArray);
  247.    T[1] = T[24] * TimeArray[1];
  248.    m = (long)u;
  249.                            /*********************/
  250.    u = 0.0;                                        /* Loop 4.           */
  251.    s = 0.0;                                        /*********************/
  252.  
  253.    dtime(TimeArray);
  254.    for( i = 1 ; i<= m ; i++ )
  255.    {
  256.    u = u + v;
  257.    s = s + u;
  258.    }
  259.    dtime(TimeArray);
  260.    T[2] = T[24] * TimeArray[1];
  261.                            /********************/
  262.    T[3] = two * T[1] - T[2];                       /* Loop Time (usec) */
  263.    if ( T[3] < 0.0 ) T[3] = 0.0;                   /* Second Estimate. */
  264.                            /********************/
  265.    m = (long)( two * ( s / u ) - v );
  266.                            /********************/
  267.    T[23] = T[2] - T[1];                            /* FADD Time (usec) */
  268.    if ( T[23] < 0.0 ) T[23] = 0.0;                 /* Second Estimate. */
  269.                            /********************/
  270.  
  271.    T[3]  = ( T[3] + T[21] ) / two;
  272.    T[23] = ( T[23] + T[22] ) / two;
  273.  
  274. /*
  275.    printf("   Loop Time (usec) = %10.4lf\n",T[3]);
  276.    printf("   FADD Time (usec) = %10.4lf\n\n",T[23]);
  277. */
  278.  
  279. /*******************************************************/
  280. /* Module 2.  Calculate Value Of PI From Taylor Series */
  281. /*            Expansion Of atan(1.0).  There Are 7     */
  282. /*            Double Precision Operations Per Loop     */
  283. /*            ( 3 +, 2 -, 1 *, and 1 / ) That are      */
  284. /*            Included in The Timing.                  */
  285. /*******************************************************/
  286.   
  287.    s  =-five;                                      /********************/
  288.    sa =-one;                                       /* Loop 5.          */
  289.                            /********************/
  290.    dtime(TimeArray);
  291.    for ( i = 1 ; i <= m ; i++ )
  292.    {
  293.    s  =-s;
  294.    sa = sa + s;
  295.    }
  296.    dtime(TimeArray);
  297.    T[4] = T[24] * TimeArray[1];
  298.    if ( T[4] < 0.0 ) T[4] = 0.0;
  299.  
  300.    sc   = (double)m;
  301.  
  302.    u = sa;                                         /*********************/
  303.    v = 0.0;                                        /* Loop 6.           */
  304.    w = 0.0;                                        /*********************/
  305.    x = 0.0;
  306.  
  307.    dtime(TimeArray);
  308.    for ( i = 1 ; i <= m ; i++)
  309.    {
  310.    s  =-s;
  311.    sa = sa + s;
  312.    u  = u + two;
  313.    x  = x +(s - u);
  314.    v  = v - s * u;
  315.    w  = w + s / u;
  316.    }
  317.    dtime(TimeArray);
  318.    T[5] = T[24] * TimeArray[1];
  319.  
  320.    T[6] = T[5] - T[4];                             /*********************/
  321.    m = (long)( sa * x  / sc );                     /*  PI Results       */
  322.    sa = four * w / five;                           /*********************/
  323.    sb = sa + five / v;
  324.    sc = 31.25;
  325.    piprg = sb - sc / (v * v * v);
  326.    pierr = piprg - piref;
  327.                            /*********************/
  328.                            /*   DO NOT REMOVE   */
  329.                            /*  THESE PRINTOUTS! */
  330.                            /*********************/
  331.    printf("   PI: Program     = %20.17lf\n",piprg);
  332.    printf("   PI: Reference   = %20.17lf\n",piref);
  333.    printf("   PI: Error       =%13.4le\n\n",pierr);
  334.  
  335. /*******************************************************/
  336. /* Module 3.  Calculate Area Under sin(x) Curve From   */
  337. /*            0.0 To PI/3.0 Using Trapazoidal Method.  */
  338. /*            Result is 0.5 .  There Are 17 Double     */
  339. /*            Precision Operations Per Loop ( 6 +, 2 -,*/
  340. /*            9 *, and 0 / ) Included In The Timing.   */
  341. /*******************************************************/
  342.   
  343.    delta = piref / ( three * (double)m );          /*********************/
  344.    s = 0.0;                                        /*  Loop 7.          */
  345.    v = 0.0;                                        /*********************/
  346.  
  347.    dtime(TimeArray);
  348.    for( i = 1 ; i <= m ; i++ )
  349.    {
  350.    v = v + one;
  351.    u = v * delta;
  352.    w = u * u;
  353.    s = s + u * ((((((A6*w-A5)*w+A4)*w-A3)*w+A2)*w+A1)*w+A0);
  354.    }
  355.    dtime(TimeArray);
  356.    T[7]  = T[24] * TimeArray[1];
  357.  
  358.    u  = piref / three;
  359.    w  = u * u;
  360.    sa = u * ((((((A6*w-A5)*w+A4)*w-A3)*w+A2)*w+A1)*w+A0) / two;
  361.    m  = (long)v;
  362.                            /*********************/
  363.    sa = delta * ( s - sa );                        /* Area Results.     */
  364.    sb = 0.5;                                       /*********************/
  365.    sc = sa - sb;
  366.                            /*********************/
  367.                            /*   DO NOT REMOVE   */
  368.    printf("   Area: Program   = %20.17lf\n",sa);   /*  THESE PRINTOUTS! */
  369.    printf("   Area: Reference = %20.17lf\n",sb);   /*********************/
  370.    printf("   Area: Error     =%13.4le\n\n",sc);
  371.  
  372.  
  373.    T[8]  = T[7] - T[3];
  374.    T[9]  = ( five * T[6] + T[8] ) / 52.0;
  375.    T[10] = one / T[9];
  376.                            /*********************/
  377.                            /*   DO NOT REMOVE   */
  378.                            /*  THESE PRINTOUTS! */
  379.                            /*********************/
  380.    printf("   Iterations      = %9ld\n",m);
  381.    printf("   BenchTime(usec) = %9.4lf\n",T[9]);
  382.    printf("   Scalar MFLOPS   = %9.4lf\n\n",T[10]);
  383.  
  384.    x = sd * (double)m;
  385.    if ( (long)x != loops )
  386.    {
  387.    printf("   Results are bogus! It appears that an optimization\n");
  388.    printf("   was done which invalidates the program and results.\n\n");
  389.    }
  390.  
  391. }
  392.  
  393.  
  394. /********************************************************/
  395. /* dtime () outputs the elapsed time in p[1] from the    */
  396. /* first call of dtime() to the second call of dtime(). */
  397. /********************************************************/
  398. #ifdef Amiga
  399. dtime(p)
  400. double p[];
  401. {
  402.    double q;
  403.  
  404.    struct   tt {
  405.       long  days;
  406.       long  minutes;
  407.       long  ticks;
  408.    } tt;
  409.  
  410.    q = p[2];
  411.  
  412.    DateStamp(&tt);
  413.  
  414.    p[2] = ( (double)(tt.ticks + (tt.minutes * 60L * 50L)) ) / (double)HZ;
  415.    p[1] = p[2] - q;
  416.    return 0;
  417. }
  418. #endif
  419.  
  420. #ifdef UNIX
  421. dtime(p)
  422. double p[];
  423. {
  424.    double q;
  425.  
  426.    q = p[2];
  427.  
  428.    getrusage(RUSAGE_SELF,&rusage);
  429.  
  430.    p[2] = (double)(rusage.ru_utime.tv_sec);
  431.    p[2] = p[2] + (double)(rusage.ru_utime.tv_usec) / 1.0e+06;
  432.    p[1] = p[2] - q;
  433.    return 0;
  434. }
  435. #endif
  436.  
  437. #ifdef UNIX_Old
  438. dtime(p)
  439. double p[];
  440. {
  441.    double q;
  442.  
  443.    q = p[2];
  444.  
  445.    times(&tms);
  446.  
  447.    p[2] = (double)(tms.tms_utime) / (double)HZ;
  448.    p[1] = p[2] - q;
  449.    return 0;
  450. }
  451. #endif
  452.  
  453.  
  454. #ifdef TURBO_C
  455. dtime(p)
  456. double p[];
  457. {
  458.    double q;
  459.  
  460.    q = p[2];
  461.  
  462.    gettime(&now);
  463.  
  464.    p[2] = 60.0 * (double)(now.ti_min);
  465.    p[2] = p[2] + (double)(now.ti_sec);
  466.    p[2] = p[2] + (double)(now.ti_hund)/(double)HZ;
  467.    p[1] = p[2] - q;
  468.    return 0;
  469. }
  470. #endif
  471.  
  472.  
  473. #ifdef MSC
  474. dtime(p)
  475. double p[];
  476. {
  477.    double q;
  478.  
  479.    q = p[2];
  480.  
  481.    tnow = clock();
  482.  
  483.    p[2] = (double)tnow / (double)HZ;
  484.    p[1] = p[2] - q;
  485.    return 0;
  486. }
  487. #endif
  488.  
  489. #ifdef _OSK
  490. dtime(p)
  491. double p[];
  492. {
  493.    double q;
  494.  
  495.    q = p[2];
  496.  
  497.    tnow = clock();
  498.  
  499.    p[2] = (double)tnow / (double)CLK_TCK;
  500.    p[1] = p[2] - q;
  501.    return 0;
  502. }
  503. #endif
  504.  
  505. /*------------------------ End flops.c code ---------------------------*/
  506.  
  507.