OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc1/] [or1ksim/] [profiler.c] - Diff between revs 847 and 879

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 847 Rev 879
Line 21... Line 21...
   by or1ksim. (use --profile option at command line, when running or1ksim.  */
   by or1ksim. (use --profile option at command line, when running or1ksim.  */
 
 
#include <stdio.h>
#include <stdio.h>
#include "profiler.h"
#include "profiler.h"
 
 
struct stack_struct {
static struct stack_struct stack[MAX_STACK];
  /* Function address */
 
  unsigned int addr;
 
 
 
  /* Cycles of function start; cycles of subfunctions are added later */
struct func_struct prof_func[MAX_FUNCS];
  unsigned int cycles;
 
 
 
  /* Return address */
 
  unsigned int raddr;
 
 
 
  /* Name of the function */
 
  char name[33];
 
} stack[MAX_STACK];
 
 
 
struct func_struct {
 
  /* Start address of function */
 
  unsigned int addr;
 
 
 
  /* Name of the function */
 
  char name[33];
 
 
 
  /* Total cycles spent in function */
 
  long cum_cycles;
 
 
 
  /* Calls to this function */
 
  long calls;
 
} func[MAX_FUNCS];
 
 
 
/* Total number of functions */
/* Total number of functions */
int nfuncs = 0;
int prof_nfuncs = 0;
 
 
/* Current depth */
/* Current depth */
int nstack = 0;
static int nstack = 0;
 
 
/* Max depth */
/* Max depth */
int maxstack = 0;
static int maxstack = 0;
 
 
/* Number of total calls */
/* Number of total calls */
int ntotcalls = 0;
static int ntotcalls = 0;
 
 
/* Number of covered calls */
/* Number of covered calls */
int nfunccalls = 0;
static int nfunccalls = 0;
 
 
/* Current cycles */
/* Current cycles */
static int cycles = 0;
int prof_cycles = 0;
 
 
/* Whether we are in cumulative mode */
/* Whether we are in cumulative mode */
static int cumulative = 0;
static int cumulative = 0;
 
 
/* Whether we should not report warnings */
/* Whether we should not report warnings */
static int quiet = 0;
static int quiet = 0;
 
 
 
/* File to read from */
 
static FILE *fprof = 0;
 
 
 
/* Print out command line help */
void prof_help ()
void prof_help ()
{
{
  printf ("profiler [-c] [-q] -g [profile_file_name]\n");
  printf ("profiler [-c] [-q] -g [profile_file_name]\n");
  printf ("\t-c\t--cumulative\t\tcumulative sum of cycles in functions\n");
  printf ("\t-c\t--cumulative\t\tcumulative sum of cycles in functions\n");
  printf ("\t-q\t--quiet\t\t\tsuppress messages\n");
  printf ("\t-q\t--quiet\t\t\tsuppress messages\n");
  printf ("\t-g\t--generate [profile_file_name]\n");
  printf ("\t-g\t--generate [profile_file_name]\n");
  printf ("\t\t\t\t\toutput profiling results to\n");
  printf ("\t\t\t\t\toutput profiling results to\n");
  printf ("\t\t\t\t\tstdout/profile_file_name\n");
  printf ("\t\t\t\t\tstdout/profile_file_name\n");
}
}
 
 
/* File to read from */
/* Acquire data from profiler file */
static FILE *fprof = 0;
int prof_acquire (char *fprofname)
 
{
int main_profiler (int argc, char *argv[]) {
 
  char fprofname[50] = "sim.profile";
 
  int line = 0;
  int line = 0;
 
 
  if (argc > 4 || argc < 2) {
 
    prof_help ();
 
    return 1;
 
  }
 
 
 
  argv++; argc--;
 
  while (argc > 0) {
 
    if (!strcmp(argv[0], "-q") || !strcmp(argv[0], "--quiet")) {
 
      quiet = 1;
 
      argv++; argc--;
 
    } else if (!strcmp(argv[0], "-c") || !strcmp(argv[0], "--cumulative")) {
 
      cumulative = 1;
 
      argv++; argc--;
 
    } else if (strcmp(argv[0], "-g") && strcmp(argv[0], "--generate")) {
 
      prof_help ();
 
      return -1;
 
    } else {
 
      argv++; argc--;
 
      if (argv[0] && argv[0][0] != '-') {
 
        strcpy (&fprofname[0], argv[0]);
 
        argv++; argc--;
 
      }
 
    }
 
  }
 
 
 
  fprof = fopen (fprofname, "rt");
  fprof = fopen (fprofname, "rt");
 
 
  if (!fprof) {
  if (!fprof) {
    fprintf (stderr, "Cannot open profile file: %s\n", fprofname);
    fprintf (stderr, "Cannot open profile file: %s\n", fprofname);
    return 1;
    return 1;
Line 130... Line 82...
    if (dir == '+') {
    if (dir == '+') {
      if (fscanf (fprof, "%08X %08X %08X %s\n", &stack[nstack].cycles, &stack[nstack].raddr,
      if (fscanf (fprof, "%08X %08X %08X %s\n", &stack[nstack].cycles, &stack[nstack].raddr,
                  &stack[nstack].addr, &stack[nstack].name[0]) != 4)
                  &stack[nstack].addr, &stack[nstack].name[0]) != 4)
        fprintf (stderr, "Error reading line #%i\n", line);
        fprintf (stderr, "Error reading line #%i\n", line);
      else {
      else {
        cycles = stack[nstack].cycles;
        prof_cycles = stack[nstack].cycles;
        nstack++;
        nstack++;
        if (nstack > maxstack)
        if (nstack > maxstack)
          maxstack = nstack;
          maxstack = nstack;
      }
      }
      ntotcalls++;
      ntotcalls++;
Line 142... Line 94...
      struct stack_struct s;
      struct stack_struct s;
      if (fscanf (fprof, "%08X %08X\n", &s.cycles, &s.raddr) != 2)
      if (fscanf (fprof, "%08X %08X\n", &s.cycles, &s.raddr) != 2)
        fprintf (stderr, "Error reading line #%i\n", line);
        fprintf (stderr, "Error reading line #%i\n", line);
      else {
      else {
        int i;
        int i;
        cycles = s.cycles;
        prof_cycles = s.cycles;
        for (i = nstack - 1; i >= 0; i--)
        for (i = nstack - 1; i >= 0; i--)
          if (stack[i].raddr == s.raddr) break;
          if (stack[i].raddr == s.raddr) break;
        if (i >= 0) {
        if (i >= 0) {
          /* pop everything above current from stack,
          /* pop everything above current from stack,
             if more than one, something went wrong */
             if more than one, something went wrong */
Line 166... Line 118...
                stack[j].cycles += time;
                stack[j].cycles += time;
 
 
            if (!quiet && i != nstack)
            if (!quiet && i != nstack)
              fprintf (stderr, "WARNING: Missaligned return call for %s (%08X) (found %s @ %08X), closing.\n", stack[nstack].name, stack[nstack].raddr, stack[i].name, stack[i].raddr);
              fprintf (stderr, "WARNING: Missaligned return call for %s (%08X) (found %s @ %08X), closing.\n", stack[nstack].name, stack[nstack].raddr, stack[i].name, stack[i].raddr);
 
 
            for (j = 0; j < nfuncs; j++)
            for (j = 0; j < prof_nfuncs; j++)
              if (stack[nstack].addr == func[j].addr) { /* function exists, append. */
              if (stack[nstack].addr == prof_func[j].addr) { /* function exists, append. */
                func[j].cum_cycles += time;
                prof_func[j].cum_cycles += time;
                func[j].calls++;
                prof_func[j].calls++;
                nfunccalls++;
                nfunccalls++;
                break;
                break;
              }
              }
            if (j >= nfuncs) { /* function does not yet exist, create new. */
            if (j >= prof_nfuncs) { /* function does not yet exist, create new. */
              func[nfuncs].cum_cycles = time;
              prof_func[prof_nfuncs].cum_cycles = time;
              func[nfuncs].calls = 1;
              prof_func[prof_nfuncs].calls = 1;
              nfunccalls++;
              nfunccalls++;
              func[nfuncs].addr = stack[nstack].addr;
              prof_func[prof_nfuncs].addr = stack[nstack].addr;
              strcpy (func[nfuncs].name, stack[nstack].name);
              strcpy (prof_func[prof_nfuncs].name, stack[nstack].name);
              nfuncs++;
              prof_nfuncs++;
            }
            }
          }
          }
        } else if (!quiet) fprintf (stderr, "WARNING: Cannot find return call for (%08X), ignoring.\n", s.raddr);
        } else if (!quiet) fprintf (stderr, "WARNING: Cannot find return call for (%08X), ignoring.\n", s.raddr);
      }
      }
    } else
    } else
      break;
      break;
  }
  }
  fclose(fprof);
  fclose(fprof);
 
}
 
 
  /* Now we have all data acquired. Print out. */
/* Print out profiling data */
 
void prof_print ()
  {
  {
    int i, j;
    int i, j;
    if (cumulative)
    if (cumulative)
      printf ("CUMULATIVE TIMES\n");
      printf ("CUMULATIVE TIMES\n");
    printf ("---------------------------------------------------------------------------\n");
    printf ("---------------------------------------------------------------------------\n");
    printf ("|function name            |addr    |# calls |avg cycles  |total cyles     |\n");
    printf ("|function name            |addr    |# calls |avg cycles  |total cyles     |\n");
    printf ("|-------------------------+--------+--------+------------+----------------|\n");
    printf ("|-------------------------+--------+--------+------------+----------------|\n");
    for (j = 0; j < nfuncs; j++) {
  for (j = 0; j < prof_nfuncs; j++) {
      int bestcyc = 0, besti = 0;
      int bestcyc = 0, besti = 0;
      for (i = 0; i < nfuncs; i++)
    for (i = 0; i < prof_nfuncs; i++)
        if (func[i].cum_cycles > bestcyc) {
      if (prof_func[i].cum_cycles > bestcyc) {
          bestcyc = func[i].cum_cycles;
        bestcyc = prof_func[i].cum_cycles;
          besti = i;
          besti = i;
        }
        }
      i = besti;
      i = besti;
      printf ("| %-24s|%08X|%8i|%12.1f|%11i,%3.0f%%|\n",
      printf ("| %-24s|%08X|%8i|%12.1f|%11i,%3.0f%%|\n",
              func[i].name, func[i].addr, func[i].calls, ((double)func[i].cum_cycles / func[i].calls), func[i].cum_cycles, (100. * func[i].cum_cycles / cycles));
            prof_func[i].name, prof_func[i].addr, prof_func[i].calls, ((double)prof_func[i].cum_cycles / prof_func[i].calls), prof_func[i].cum_cycles, (100. * prof_func[i].cum_cycles / prof_cycles));
      func[i].cum_cycles = -1;
    prof_func[i].cum_cycles = -1;
    }
    }
    printf ("---------------------------------------------------------------------------\n");
    printf ("---------------------------------------------------------------------------\n");
  }
  printf ("Total %i functions, %i cycles.\n", prof_nfuncs, prof_cycles);
  printf ("Total %i functions, %i cycles.\n", nfuncs, cycles);
 
  printf ("Total function calls %i/%i (max depth %i).\n", nfunccalls, ntotcalls, maxstack);
  printf ("Total function calls %i/%i (max depth %i).\n", nfunccalls, ntotcalls, maxstack);
 
}
 
 
 
/* Set options */
 
void prof_set (int _quiet, int _cumulative)
 
{
 
  quiet = _quiet;
 
  cumulative = _cumulative;
 
}
 
 
 
int main_profiler (int argc, char *argv[]) {
 
  char fprofname[50] = "sim.profile";
 
 
 
  if (argc > 4 || argc < 2) {
 
    prof_help ();
 
    return 1;
 
  }
 
 
 
  argv++; argc--;
 
  while (argc > 0) {
 
    if (!strcmp(argv[0], "-q") || !strcmp(argv[0], "--quiet")) {
 
      quiet = 1;
 
      argv++; argc--;
 
    } else if (!strcmp(argv[0], "-c") || !strcmp(argv[0], "--cumulative")) {
 
      cumulative = 1;
 
      argv++; argc--;
 
    } else if (strcmp(argv[0], "-g") && strcmp(argv[0], "--generate")) {
 
      prof_help ();
 
      return -1;
 
    } else {
 
      argv++; argc--;
 
      if (argv[0] && argv[0][0] != '-') {
 
        strcpy (&fprofname[0], argv[0]);
 
        argv++; argc--;
 
      }
 
    }
 
  }
 
 
 
  prof_acquire (fprofname);
 
 
 
  /* Now we have all data acquired. Print out. */
 
  prof_print ();
  return 0;
  return 0;
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.