Home | History | Annotate | Line # | Download | only in gdb.trace
tspeed.c revision 1.8
      1  1.1  christos /* This testcase is part of GDB, the GNU debugger.
      2  1.1  christos 
      3  1.8  christos    Copyright 2010-2019 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.8  christos #include <unistd.h>
     32  1.1  christos 
     33  1.1  christos int trace_speed_test (void);
     34  1.1  christos 
     35  1.1  christos /* We mark these globals as volatile so the speed-measuring loops
     36  1.1  christos    don't get totally emptied out at high optimization levels.  */
     37  1.1  christos 
     38  1.1  christos volatile int globfoo, globfoo2, globfoo3;
     39  1.1  christos 
     40  1.1  christos volatile short globarr[80000];
     41  1.1  christos 
     42  1.1  christos int init_iters = 10 * 1000;
     43  1.1  christos 
     44  1.1  christos int iters;
     45  1.1  christos 
     46  1.1  christos int max_iters = 1000 * 1000 * 1000;
     47  1.1  christos 
     48  1.1  christos int numtps = 1;
     49  1.1  christos 
     50  1.1  christos unsigned long long now2, now3, now4, now5;
     51  1.1  christos int total1, total2, idelta, mindelta, nsdelta;
     52  1.1  christos int nspertp = 0;
     53  1.1  christos 
     54  1.1  christos /* Return CPU usage (both user and system - trap-based tracepoints use
     55  1.1  christos    a bunch of system time).  */
     56  1.1  christos 
     57  1.1  christos unsigned long long
     58  1.1  christos myclock ()
     59  1.1  christos {
     60  1.6  christos   struct timeval tm;
     61  1.6  christos   gettimeofday (&tm, NULL);
     62  1.6  christos   return (((unsigned long long) tm.tv_sec) * 1000000) + tm.tv_usec;
     63  1.1  christos }
     64  1.1  christos 
     65  1.1  christos int
     66  1.1  christos main(int argc, char **argv)
     67  1.1  christos {
     68  1.1  christos   int problem;
     69  1.1  christos 
     70  1.1  christos   iters = init_iters;
     71  1.1  christos 
     72  1.1  christos   while (1)
     73  1.1  christos     {
     74  1.1  christos       numtps = 1;  /* set pre-run breakpoint here */
     75  1.1  christos 
     76  1.1  christos       /* Keep trying the speed test, with more iterations, until
     77  1.1  christos 	 we get to a reasonable number.  */
     78  1.1  christos       while (problem = trace_speed_test())
     79  1.1  christos 	{
     80  1.1  christos 	  /* If iteration isn't working, give up.  */
     81  1.1  christos 	  if (iters > max_iters)
     82  1.1  christos 	    {
     83  1.1  christos 	      printf ("Gone over %d iterations, giving up\n", max_iters);
     84  1.1  christos 	      break;
     85  1.1  christos 	    }
     86  1.1  christos 	  if (problem < 0)
     87  1.1  christos 	    {
     88  1.8  christos 	      printf ("Negative times, giving up\n");
     89  1.1  christos 	      break;
     90  1.1  christos 	    }
     91  1.1  christos 
     92  1.1  christos 	  iters *= 2;
     93  1.1  christos 	  printf ("Doubled iterations to %d\n", iters);
     94  1.1  christos 	}
     95  1.1  christos 
     96  1.1  christos       printf ("Tracepoint time is %d ns\n", nspertp);
     97  1.1  christos 
     98  1.1  christos       /* This is for the benefit of interactive testing and attaching,
     99  1.1  christos 	 keeps the program from pegging the machine.  */
    100  1.1  christos       sleep (1);  /* set post-run breakpoint here */
    101  1.1  christos 
    102  1.1  christos       /* Issue a little bit of output periodically, so we can see if
    103  1.1  christos 	 program is alive or hung.  */
    104  1.1  christos       printf ("%s keeping busy, clock=%llu\n", argv[0], myclock ());
    105  1.1  christos     }
    106  1.1  christos   return 0;
    107  1.1  christos }
    108  1.1  christos 
    109  1.1  christos int
    110  1.1  christos trace_speed_test (void)
    111  1.1  christos {
    112  1.1  christos   int i;
    113  1.1  christos 
    114  1.1  christos   /* Overall loop run time deltas under 1 ms are likely noise and
    115  1.1  christos      should be ignored.  */
    116  1.1  christos   mindelta = 1000;
    117  1.1  christos 
    118  1.1  christos   // The bodies of the two loops following must be identical.
    119  1.1  christos 
    120  1.1  christos   now2 = myclock ();
    121  1.1  christos   globfoo2 = 1;
    122  1.1  christos   for (i = 0; i < iters; ++i)
    123  1.1  christos     {
    124  1.1  christos       globfoo2 *= 45;
    125  1.1  christos       globfoo2 += globfoo + globfoo3;
    126  1.1  christos       globfoo2 *= globfoo + globfoo3;
    127  1.1  christos       globfoo2 -= globarr[4] + globfoo3;
    128  1.1  christos       globfoo2 *= globfoo + globfoo3;
    129  1.1  christos       globfoo2 += globfoo + globfoo3;
    130  1.1  christos     }
    131  1.1  christos   now3 = myclock ();
    132  1.1  christos   total1 = now3 - now2;
    133  1.1  christos 
    134  1.1  christos   now4 = myclock ();
    135  1.1  christos   globfoo2 = 1;
    136  1.1  christos   for (i = 0; i < iters; ++i)
    137  1.1  christos     {
    138  1.1  christos       globfoo2 *= 45;
    139  1.1  christos       globfoo2 += globfoo + globfoo3;  /* set tracepoint here */
    140  1.1  christos       globfoo2 *= globfoo + globfoo3;
    141  1.1  christos       globfoo2 -= globarr[4] + globfoo3;
    142  1.1  christos       globfoo2 *= globfoo + globfoo3;
    143  1.1  christos       globfoo2 += globfoo + globfoo3;
    144  1.1  christos     }
    145  1.1  christos   now5 = myclock ();
    146  1.1  christos   total2 = now5 - now4;
    147  1.1  christos 
    148  1.1  christos   /* Report on the test results.  */
    149  1.1  christos 
    150  1.1  christos   nspertp = 0;
    151  1.1  christos 
    152  1.1  christos   idelta = total2 - total1;
    153  1.1  christos 
    154  1.1  christos   printf ("Loops took %d usec and %d usec, delta is %d usec, %d iterations\n",
    155  1.1  christos 	  total1, total2, idelta, iters);
    156  1.1  christos 
    157  1.1  christos   /* If the second loop seems to run faster, things are weird so give up.  */
    158  1.1  christos   if (idelta < 0)
    159  1.1  christos     return -1;
    160  1.1  christos 
    161  1.1  christos   if (idelta > mindelta
    162  1.6  christos       /* Total test time should be between 15 and 30 seconds.  */
    163  1.6  christos       && (total1 + total2) > (15 * 1000000)
    164  1.6  christos       && (total1 + total2) < (30 * 1000000))
    165  1.1  christos     {
    166  1.1  christos       nsdelta = (((unsigned long long) idelta) * 1000) / iters;
    167  1.1  christos       printf ("Second loop took %d ns longer per iter than first\n", nsdelta);
    168  1.1  christos       nspertp = nsdelta / numtps;
    169  1.1  christos       printf ("%d ns per tracepoint\n", nspertp);
    170  1.1  christos       printf ("Base iteration time %d ns\n",
    171  1.1  christos 	      ((int) (((unsigned long long) total1) * 1000) / iters));
    172  1.1  christos       printf ("Total test time %d secs\n", ((int) ((now5 - now2) / 1000000)));
    173  1.1  christos 
    174  1.1  christos       /* Speed test ran with no problem.  */
    175  1.1  christos       return 0;
    176  1.1  christos     }
    177  1.1  christos 
    178  1.1  christos   /* The test run was too brief, or otherwise not useful.  */
    179  1.1  christos   return 1;
    180  1.1  christos }
    181