home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cputime.zip / cputimes.c < prev    next >
C/C++ Source or Header  |  1994-04-18  |  6KB  |  230 lines

  1. /* time.c -- produce a 1-page summary of cpu times of various C constructs
  2.  * To port to a new machine, change the following:
  3.  *    BASEN:    Start around 10000, increase by *10 until no question marks
  4.  *    Macro processor: define ANSIIMAC 1 for Ansii C, undef for old C
  5.  *    WARNRANGE: print ? after CPU time if max clicks - min clicks >
  6.  *           WARNRANGE * mean clicks
  7.  *    Times: typical values of CLOCKS_PER_SEC: Vax=60  Cray=105296000
  8.  *    For large values, change %5d in macro loop1, 99999 in minclicks;
  9.  *  10 Oct 1990  Bentley, Kernighan, Van Wyk
  10.  *  13 Jan 1991  ANSI C edit by Grosse;  avoid common ungetc bug in scanf;
  11.  *    clean up junk file;
  12.  *
  13.  *  16 Apr 1994  adpated to OS/2 using both IBM and Microsoft compilers;
  14.  *               replaced close() calls with fclose(), added stdlib.h to
  15.  *               the include list - J. M. Hughes, jmh@noao.edu
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <math.h>
  20. #include <time.h>
  21. #include <stdlib.h>             /* jmh */
  22.  
  23. #define BASEN 1000000
  24. #define WARNRANGE 0.4
  25. #define quoted(TEXT) #TEXT
  26.  
  27. struct stacknode {
  28.     int val;
  29.     struct stacknode *next;
  30. };
  31. typedef struct stacknode *Stackp;
  32. Stackp    stackroot;
  33.  
  34. void push(i)
  35. int i;
  36. {
  37.     Stackp p;
  38.  
  39.     p = (Stackp) malloc(sizeof(struct stacknode));
  40.     p->val = i;
  41.     p->next = stackroot;
  42.     stackroot = p;
  43. }
  44.  
  45. int pop()
  46. {
  47.     int    i;
  48.  
  49.     i = stackroot->val;
  50.     stackroot = stackroot->next;
  51.     return i;
  52. }
  53.  
  54. /* Main macros for experiments */
  55.  
  56.  
  57. #define loop1(CODE) loop1ctr++; \
  58.     for (i = 0; i < n; i++) { CODE; } \
  59.     loop1next = clock(); \
  60.     thisclicks = loop1next - loop1start; \
  61.     sumclicks += thisclicks; \
  62.     if (thisclicks < minclicks) minclicks = thisclicks; \
  63.     if (thisclicks > maxclicks) maxclicks = thisclicks; \
  64.     printf("%5d", (loop1next - loop1start)/1000); \
  65.     loop1start = loop1next;
  66.  
  67. #define loop(CODE) printf("  %-30s", quoted(CODE)); \
  68.     minclicks = 99999999; maxclicks = -1; sumclicks = 0; \
  69.     loop1ctr = 0; \
  70.     loop1start = clock(); \
  71.     loop1(CODE) \
  72.     loop1(CODE) \
  73.     i0 = i1 + i2 + i3; \
  74.     loop1(CODE) \
  75.     i0 = i1 + i2 + i3 - i1 - i2 - i3; \
  76.     loop1(CODE) \
  77.     i0 = i1 + i2 + i3 + i1*i2 + i2*i3 + i1*i3; \
  78.     loop1(CODE) \
  79.     queststr = ""; \
  80.     if (loop1ctr * (float)(maxclicks - minclicks) > WARNRANGE *  sumclicks) \
  81.         queststr = "?"; \
  82.     lastmics = sumclicks * 1000000.0 / ((float)(CLOCKS_PER_SEC) * n * loop1ctr); \
  83.     printf("%10.2f%s\n", lastmics - basemics, queststr);
  84.  
  85. #define title(TEXT) printf("%s (n=%d)\n", TEXT, n);
  86.  
  87. /* The experiment */
  88.  
  89. int sum1(a) int a; { return a; }
  90. int sum2(a, b) int a, b; { return a + b; }
  91. int sum3(a, b, c) int a, b, c; { return a + b + c; }
  92.  
  93. main()
  94. {
  95.     int    loop1start, loop1next, loop1ctr;
  96.     float    lastmics, basemics;
  97.     int    minclicks, maxclicks, sumclicks, thisclicks;
  98.     int    i, n, basen;
  99.     int    i0, i1, i2, i3, i4;
  100.     float    f0, f1, f2, f3;
  101.     int    *v;
  102.     char    *queststr;
  103.     char    s[100];
  104.     char    fname[20];
  105.     FILE    *fp;
  106.     /* The following strings are variables because some macro processors
  107.       don't handle quoted strings in quoted arguments.
  108.       They are not just pointers to string literals because some
  109.       scanf's write on their input. */
  110.     char    s0123456789[20];
  111.     char    sa123456789[20];
  112.     char    s12345[20];
  113.     char    s123_45[20];
  114.     char    sd[20];
  115.     char    sdn[20];
  116.     char    sf[20];
  117.     char    sf62[20];
  118.     strcpy(s0123456789,"0123456789");
  119.     strcpy(sa123456789,"a123456789");
  120.     strcpy(s12345,"12345");
  121.     strcpy(s123_45,"123.45");
  122.     strcpy(sd,"%d");
  123.     strcpy(sdn,"%d\n");
  124.     strcpy(sf,"%f");
  125.     strcpy(sf62,"%f6.2");
  126.  
  127.     setbuf(stdout, (char *) 0);    /* No buffering to watch output */
  128.     printf("  Operation                         Clicks for each trial ");
  129.     printf("   Mics/N\n");
  130.  
  131.     basen = BASEN;
  132.     n = basen;
  133.     title("Null Loop")
  134.     i0 = i1 = i2 = i3 = 5;
  135.     f0 = f1 = f2 = f3 = 5.0;
  136.     basemics = 0.0;
  137.     loop({})
  138.     basemics = lastmics;
  139.  
  140.     title("Int Operations");
  141.     i1 = i2 = i3 = 5;
  142.     loop(i1++)
  143.     loop(i1 = i2)
  144.     loop(i1 = i2 + i3)
  145.     loop(i1 = i2 - i3)
  146.     loop(i1 = i2 * i3)
  147.     loop(i1 = i2 / i3)
  148.     loop(i1 = i2 % i3)
  149.  
  150.     title("Float Operations");
  151.     f1 = f2 = f3 = 5.0;
  152.     loop(f1 = f2)
  153.     loop(f1 = f2 + f3)
  154.     loop(f1 = f2 - f3)
  155.     loop(f1 = f2 * f3)
  156.     loop(f1 = f2 / f3)
  157.  
  158.     title("Numeric Conversions");
  159.     f1 = 123456.789;
  160.     i1 = 123456;
  161.     loop(i1 = f1)
  162.     loop(f1 = i1)
  163.  
  164.     title("Integer Vector Operations");
  165.     v = (int *) malloc(n * sizeof(int));
  166.     for (i = 0; i < n; i++)
  167.         v[i] = 0;
  168.     loop(v[i] = i)
  169.     loop(v[v[i]] = i)
  170.     loop(v[v[v[i]]] = i)
  171.     free(v);
  172.  
  173.     title("Control Structures");
  174.     i1 = i2 = i3 = 5;
  175.     loop(if (i == 5) i1++)
  176.     loop(if (i != 5) i1++)
  177.     loop(while (i < 0) i1++)
  178.     loop(i1 = sum1(i2))
  179.     loop(i1 = sum2(i2, i3))
  180.     loop(i1 = sum3(i2, i3, i4))
  181.  
  182.     n = basen/100;
  183.     strcpy(fname, "junk");
  184.     title("Input/Output");
  185.     strcpy(s, "1234\n");
  186.     fp = fopen(fname, "w");
  187.     loop(fputs(s, fp))
  188.     fclose(fp);                             /* jmh */ 
  189.     fp = fopen(fname, "r");
  190.     loop(fgets(s, 9, fp))
  191.     fclose(fp);                             /* jmh */ 
  192.     fp = fopen(fname, "w");
  193.     loop(fprintf(fp, sdn, i))
  194.     fclose(fp);                             /* jmh */ 
  195.     fp = fopen(fname, "r");
  196.     loop(fscanf(fp, sd, &i1))
  197.     fclose(fp);                             /* jmh */ 
  198.     unlink(fname);
  199.  
  200.     n = basen/100;
  201.     title("Malloc");
  202.     loop(free(malloc(8)))
  203.     loop(push(i))
  204.     loop(i1 = pop())
  205.  
  206.     n = basen/10;
  207.     title("String Functions");
  208.     loop(strcpy(s, s0123456789))
  209.     loop(i1 = strcmp(s, s))
  210.     loop(i1 = strcmp(s, sa123456789))
  211.  
  212.     n = basen/100;
  213.     title("String/Number Conversions");
  214.     loop(i1 = atoi(s12345))
  215.     loop(sscanf(s12345, sd, &i1))
  216.     loop(sprintf(s, sd, i))
  217.     loop(f1 = atof(s123_45))
  218.     loop(sscanf(s123_45, sf, &f1))
  219.     loop(sprintf(s, sf62, 123.45))
  220.  
  221.     n = basen/100;
  222.     title("Math Functions");
  223.     loop(i1 = rand())
  224.     f2 = 5.0;
  225.     loop(f1 = log(f2))
  226.     loop(f1 = exp(f2))
  227.     loop(f1 = sin(f2))
  228.     loop(f1 = sqrt(f2))
  229. }
  230.