Home | History | Annotate | Line # | Download | only in gdb.trace
tspeed.c revision 1.1
      1  1.1  christos /* This testcase is part of GDB, the GNU debugger.
      2  1.1  christos 
      3  1.1  christos    Copyright 2010-2014 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This program is free software; you can redistribute it and/or modify
      6  1.1  christos    it under the terms of the GNU General Public License as published by
      7  1.1  christos    the Free Software Foundation; either version 3 of the License, or
      8  1.1  christos    (at your option) any later version.
      9  1.1  christos 
     10  1.1  christos    This program is distributed in the hope that it will be useful,
     11  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  1.1  christos    GNU General Public License for more details.
     14  1.1  christos 
     15  1.1  christos    You should have received a copy of the GNU General Public License
     16  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17  1.1  christos 
     18  1.1  christos /* This program tests tracepoint speed. It consists of two identical
     19  1.1  christos    loops, which in normal execution will run for exactly the same
     20  1.1  christos    amount of time. A tracepoint in the second loop will slow it down
     21  1.1  christos    by some amount, and then the program will report the slowdown
     22  1.1  christos    observed.  */
     23  1.1  christos 
     24  1.1  christos /* While primarily designed for the testsuite, it can also be used
     25  1.1  christos    for interactive testing.  */
     26  1.1  christos 
     27  1.1  christos #include <stdio.h>
     28  1.1  christos #include <time.h>
     29  1.1  christos #include <sys/time.h>
     30  1.1  christos #include <sys/resource.h>
     31  1.1  christos 
     32  1.1  christos int trace_speed_test (void);
     33  1.1  christos 
     34  1.1  christos /* We mark these globals as volatile so the speed-measuring loops
     35  1.1  christos    don't get totally emptied out at high optimization levels.  */
     36  1.1  christos 
     37  1.1  christos volatile int globfoo, globfoo2, globfoo3;
     38  1.1  christos 
     39  1.1  christos volatile short globarr[80000];
     40  1.1  christos 
     41  1.1  christos int init_iters = 10 * 1000;
     42  1.1  christos 
     43  1.1  christos int iters;
     44  1.1  christos 
     45  1.1  christos int max_iters = 1000 * 1000 * 1000;
     46  1.1  christos 
     47  1.1  christos int numtps = 1;
     48  1.1  christos 
     49  1.1  christos unsigned long long now2, now3, now4, now5;
     50  1.1  christos int total1, total2, idelta, mindelta, nsdelta;
     51  1.1  christos int nspertp = 0;
     52  1.1  christos 
     53  1.1  christos /* Return CPU usage (both user and system - trap-based tracepoints use
     54  1.1  christos    a bunch of system time).  */
     55  1.1  christos 
     56  1.1  christos unsigned long long
     57  1.1  christos myclock ()
     58  1.1  christos {
     59  1.1  christos   struct timeval tm, tm2;
     60  1.1  christos   struct rusage ru;
     61  1.1  christos   getrusage (RUSAGE_SELF, &ru);
     62  1.1  christos   tm = ru.ru_utime;
     63  1.1  christos   tm2 = ru.ru_stime;
     64  1.1  christos   return (((unsigned long long) tm.tv_sec) * 1000000) + tm.tv_usec
     65  1.1  christos     + (((unsigned long long) tm2.tv_sec) * 1000000) + tm2.tv_usec;
     66  1.1  christos }
     67  1.1  christos 
     68  1.1  christos int
     69  1.1  christos main(int argc, char **argv)
     70  1.1  christos {
     71  1.1  christos   int problem;
     72  1.1  christos 
     73  1.1  christos   iters = init_iters;
     74  1.1  christos 
     75  1.1  christos   while (1)
     76  1.1  christos     {
     77  1.1  christos       numtps = 1;  /* set pre-run breakpoint here */
     78  1.1  christos 
     79  1.1  christos       /* Keep trying the speed test, with more iterations, until
     80  1.1  christos 	 we get to a reasonable number.  */
     81  1.1  christos       while (problem = trace_speed_test())
     82  1.1  christos 	{
     83  1.1  christos 	  /* If iteration isn't working, give up.  */
     84  1.1  christos 	  if (iters > max_iters)
     85  1.1  christos 	    {
     86  1.1  christos 	      printf ("Gone over %d iterations, giving up\n", max_iters);
     87  1.1  christos 	      break;
     88  1.1  christos 	    }
     89  1.1  christos 	  if (problem < 0)
     90  1.1  christos 	    {
     91  1.1  christos 	      printf ("Negative times, giving up\n", max_iters);
     92  1.1  christos 	      break;
     93  1.1  christos 	    }
     94  1.1  christos 
     95  1.1  christos 	  iters *= 2;
     96  1.1  christos 	  printf ("Doubled iterations to %d\n", iters);
     97  1.1  christos 	}
     98  1.1  christos 
     99  1.1  christos       printf ("Tracepoint time is %d ns\n", nspertp);
    100  1.1  christos 
    101  1.1  christos       /* This is for the benefit of interactive testing and attaching,
    102  1.1  christos 	 keeps the program from pegging the machine.  */
    103  1.1  christos       sleep (1);  /* set post-run breakpoint here */
    104  1.1  christos 
    105  1.1  christos       /* Issue a little bit of output periodically, so we can see if
    106  1.1  christos 	 program is alive or hung.  */
    107  1.1  christos       printf ("%s keeping busy, clock=%llu\n", argv[0], myclock ());
    108  1.1  christos     }
    109  1.1  christos   return 0;
    110  1.1  christos }
    111  1.1  christos 
    112  1.1  christos int
    113  1.1  christos trace_speed_test (void)
    114  1.1  christos {
    115  1.1  christos   int i;
    116  1.1  christos 
    117  1.1  christos   /* Overall loop run time deltas under 1 ms are likely noise and
    118  1.1  christos      should be ignored.  */
    119  1.1  christos   mindelta = 1000;
    120  1.1  christos 
    121  1.1  christos   // The bodies of the two loops following must be identical.
    122  1.1  christos 
    123  1.1  christos   now2 = myclock ();
    124  1.1  christos   globfoo2 = 1;
    125  1.1  christos   for (i = 0; i < iters; ++i)
    126  1.1  christos     {
    127  1.1  christos       globfoo2 *= 45;
    128  1.1  christos       globfoo2 += globfoo + globfoo3;
    129  1.1  christos       globfoo2 *= globfoo + globfoo3;
    130  1.1  christos       globfoo2 -= globarr[4] + globfoo3;
    131  1.1  christos       globfoo2 *= globfoo + globfoo3;
    132  1.1  christos       globfoo2 += globfoo + globfoo3;
    133  1.1  christos     }
    134  1.1  christos   now3 = myclock ();
    135  1.1  christos   total1 = now3 - now2;
    136  1.1  christos 
    137  1.1  christos   now4 = myclock ();
    138  1.1  christos   globfoo2 = 1;
    139  1.1  christos   for (i = 0; i < iters; ++i)
    140  1.1  christos     {
    141  1.1  christos       globfoo2 *= 45;
    142  1.1  christos       globfoo2 += globfoo + globfoo3;  /* set tracepoint here */
    143  1.1  christos       globfoo2 *= globfoo + globfoo3;
    144  1.1  christos       globfoo2 -= globarr[4] + globfoo3;
    145  1.1  christos       globfoo2 *= globfoo + globfoo3;
    146  1.1  christos       globfoo2 += globfoo + globfoo3;
    147  1.1  christos     }
    148  1.1  christos   now5 = myclock ();
    149  1.1  christos   total2 = now5 - now4;
    150  1.1  christos 
    151  1.1  christos   /* Report on the test results.  */
    152  1.1  christos 
    153  1.1  christos   nspertp = 0;
    154  1.1  christos 
    155  1.1  christos   idelta = total2 - total1;
    156  1.1  christos 
    157  1.1  christos   printf ("Loops took %d usec and %d usec, delta is %d usec, %d iterations\n",
    158  1.1  christos 	  total1, total2, idelta, iters);
    159  1.1  christos 
    160  1.1  christos   /* If the second loop seems to run faster, things are weird so give up.  */
    161  1.1  christos   if (idelta < 0)
    162  1.1  christos     return -1;
    163  1.1  christos 
    164  1.1  christos   if (idelta > mindelta
    165  1.1  christos       /* Total test time should be between 2 and 5 seconds.  */
    166  1.1  christos       && (total1 + total2) > (2 * 1000000)
    167  1.1  christos       && (total1 + total2) < (5 * 1000000))
    168  1.1  christos     {
    169  1.1  christos       nsdelta = (((unsigned long long) idelta) * 1000) / iters;
    170  1.1  christos       printf ("Second loop took %d ns longer per iter than first\n", nsdelta);
    171  1.1  christos       nspertp = nsdelta / numtps;
    172  1.1  christos       printf ("%d ns per tracepoint\n", nspertp);
    173  1.1  christos       printf ("Base iteration time %d ns\n",
    174  1.1  christos 	      ((int) (((unsigned long long) total1) * 1000) / iters));
    175  1.1  christos       printf ("Total test time %d secs\n", ((int) ((now5 - now2) / 1000000)));
    176  1.1  christos 
    177  1.1  christos       /* Speed test ran with no problem.  */
    178  1.1  christos       return 0;
    179  1.1  christos     }
    180  1.1  christos 
    181  1.1  christos   /* The test run was too brief, or otherwise not useful.  */
    182  1.1  christos   return 1;
    183  1.1  christos }
    184