This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH][RFA]: sim/common: Cpu Frequence and Exec Time


Hi,

The attached patch adds a field to the common cpu profiling
information which represents the clock frequency of the CPU. The
new field is PROFILE_CPU_FREQ and it can be set internally by the
simulator (intended to be used for the default setting) or by the
user via the new simulator command line option:

--profile-cpu-frequency=<frequency>

where <frequency> is an integer optionally followed by the suffix
mhz or khz or any non-ambiguous abbreviation. The suffix is not
case sensitive. Example:

--profile-cpu-frequency=400mhz

Simulators should override a frequency of 0 with the appropriate
default.

If the frequency has been set and profiling is enabled, then the
profile output will contain a calculation of the simulated
execution time based on the number of cycles executed and the
given frequency.

I'm seeking approval to commit this. This was added to on of our
simuators at the request of a customer, and I thought it would be
useful in general.

Dave
2000-07-27  Dave Brolley  <brolley@redhat.com>

	* sim-profile.h (PROFILE_DATA): Add cpu_freq.
	(PROFILE_CPU_FREQ): New macro.
	* sim-profile.c (OPTION_PROFILE_CPU_FREQUENCY): New enumerator.
	(profile-options): Add profile-cpu-frequency.
	(parse_frequency): New function.
	(profile_option_handler): Handle OPTION_PROFILE_CPU_FREQUENCY.
	(profile_print_speed): Print cpu frequency and simulated execution time.
	Re-indent other items to match.
Index: sim/common/sim-profile.c
===================================================================
RCS file: /cvs/src/src/sim/common/sim-profile.c,v
retrieving revision 1.1.1.2
diff -c -p -r1.1.1.2 sim-profile.c
*** sim-profile.c	1999/12/22 21:45:38	1.1.1.2
--- sim-profile.c	2000/07/27 16:43:26
*************** enum {
*** 48,53 ****
--- 48,54 ----
    OPTION_PROFILE_MODEL,
    OPTION_PROFILE_FILE,
    OPTION_PROFILE_CORE,
+   OPTION_PROFILE_CPU_FREQUENCY,
    OPTION_PROFILE_PC,
    OPTION_PROFILE_PC_RANGE,
    OPTION_PROFILE_PC_GRANULARITY,
*************** static const OPTION profile_options[] = 
*** 71,76 ****
--- 72,81 ----
    { {"profile-model", optional_argument, NULL, OPTION_PROFILE_MODEL},
        '\0', "on|off", "Perform model profiling",
        profile_option_handler },
+   { {"profile-cpu-frequency", required_argument, NULL,
+      OPTION_PROFILE_CPU_FREQUENCY},
+       '\0', "CPU FREQUENCY", "Specify the speed of the simulated cpu clock",
+       profile_option_handler },
  
    { {"profile-file", required_argument, NULL, OPTION_PROFILE_FILE},
        '\0', "FILE NAME", "Specify profile output file",
*************** sim_profile_set_option (SIM_DESC sd, con
*** 189,194 ****
--- 194,246 ----
  }
  
  static SIM_RC
+ parse_frequency (SIM_DESC sd, const char *arg, unsigned long *freq)
+ {
+   const char *ch;
+   /* First, parse a decimal number.  */
+   *freq = 0;
+   ch = arg;
+   if (isdigit (*arg))
+     {
+       for (/**/; *ch != '\0'; ++ch)
+ 	{
+ 	  if (! isdigit (*ch))
+ 	    break;
+ 	  *freq = *freq * 10 + (*ch - '0');
+ 	}
+ 
+       /* Accept KHz, MHz or Hz as a suffix.  */
+       if (tolower (*ch) == 'm')
+ 	{
+ 	  *freq *= 1000000;
+ 	  ++ch;
+ 	}
+       else if (tolower (*ch) == 'k')
+ 	{
+ 	  *freq *= 1000;
+ 	  ++ch;
+ 	}
+ 
+       if (tolower (*ch) == 'h')
+ 	{
+ 	  ++ch;
+ 	  if (tolower (*ch) == 'z')
+ 	    ++ch;
+ 	}
+     }
+ 
+   if (*ch != '\0')
+     {
+       sim_io_eprintf (sd, "Invalid argument for --profile-cpu-frequency: %s\n",
+ 		      arg);
+       *freq = 0;
+       return SIM_RC_FAIL;
+     }
+ 
+   return SIM_RC_OK;
+ }
+ 
+ static SIM_RC
  profile_option_handler (SIM_DESC sd,
  			sim_cpu *cpu,
  			int opt,
*************** profile_option_handler (SIM_DESC sd,
*** 237,242 ****
--- 289,306 ----
  	sim_io_eprintf (sd, "Model profiling not compiled in, `--profile-model' ignored\n");
        break;
  
+     case OPTION_PROFILE_CPU_FREQUENCY :
+       {
+ 	unsigned long val;
+ 	SIM_RC rc = parse_frequency (sd, arg, &val);
+ 	if (rc == SIM_RC_OK)
+ 	  {
+ 	    for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
+ 	      PROFILE_CPU_FREQ (CPU_PROFILE_DATA (STATE_CPU (sd,cpu_nr))) = val;
+ 	  }
+ 	return rc;
+       }
+ 
      case OPTION_PROFILE_FILE :
        /* FIXME: Might want this to apply to pc profiling only,
  	 or have two profile file options.  */
*************** profile_print_speed (sim_cpu *cpu)
*** 924,953 ****
    PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
    unsigned long milliseconds = sim_events_elapsed_time (sd);
    unsigned long total = PROFILE_TOTAL_INSN_COUNT (data);
    char comma_buf[20];
  
    sim_io_printf (sd, "Simulator Execution Speed\n\n");
  
    if (total != 0)
!     sim_io_printf (sd, "  Total instructions:   %s\n", COMMAS (total));
  
    if (milliseconds < 1000)
!     sim_io_printf (sd, "  Total execution time: < 1 second\n\n");
    else
      {
        /* The printing of the time rounded to 2 decimal places makes the speed
  	 calculation seem incorrect [even though it is correct].  So round
  	 MILLISECONDS first. This can marginally affect the result, but it's
  	 better that the user not perceive there's a math error.  */
!       double secs = (double) milliseconds / 1000;
        secs = ((double) (unsigned long) (secs * 100 + .5)) / 100;
!       sim_io_printf (sd, "  Total execution time: %.2f seconds\n", secs);
        /* Don't confuse things with data that isn't useful.
  	 If we ran for less than 2 seconds, only use the data if we
  	 executed more than 100,000 insns.  */
        if (secs >= 2 || total >= 100000)
! 	sim_io_printf (sd, "  Simulator speed:      %s insns/second\n\n",
  		       COMMAS ((unsigned long) ((double) total / secs)));
      }
  }
  
--- 988,1042 ----
    PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
    unsigned long milliseconds = sim_events_elapsed_time (sd);
    unsigned long total = PROFILE_TOTAL_INSN_COUNT (data);
+   double clock = PROFILE_CPU_FREQ (data);
+   double secs;
    char comma_buf[20];
  
    sim_io_printf (sd, "Simulator Execution Speed\n\n");
  
    if (total != 0)
!     sim_io_printf (sd, "  Total instructions:      %s\n", COMMAS (total));
  
    if (milliseconds < 1000)
!     sim_io_printf (sd, "  Total execution time:    < 1 second\n\n");
    else
      {
        /* The printing of the time rounded to 2 decimal places makes the speed
  	 calculation seem incorrect [even though it is correct].  So round
  	 MILLISECONDS first. This can marginally affect the result, but it's
  	 better that the user not perceive there's a math error.  */
!       secs = (double) milliseconds / 1000;
        secs = ((double) (unsigned long) (secs * 100 + .5)) / 100;
!       sim_io_printf (sd, "  Total execution time   : %.2f seconds\n", secs);
        /* Don't confuse things with data that isn't useful.
  	 If we ran for less than 2 seconds, only use the data if we
  	 executed more than 100,000 insns.  */
        if (secs >= 2 || total >= 100000)
! 	sim_io_printf (sd, "  Simulator speed:         %s insns/second\n",
  		       COMMAS ((unsigned long) ((double) total / secs)));
+     }
+ 
+   /* Print simulated execution time if the cpu frequency has been specified.  */
+   if (clock != 0)
+     {
+       if (clock >= 1000000)
+ 	sim_io_printf (sd, "  Simulated cpu frequency: %.2f MHz\n",
+ 		       clock / 1000000);
+       else
+ 	sim_io_printf (sd, "  Simulated cpu frequency: %.2f Hz\n", clock);
+ 
+       if (PROFILE_FLAGS (data) [PROFILE_MODEL_IDX])
+ 	{
+ 	  /* The printing of the time rounded to 2 decimal places makes the
+ 	     speed calculation seem incorrect [even though it is correct].
+ 	     So round 	 SECS first. This can marginally affect the result,
+ 	     but it's 	 better that the user not perceive there's a math
+ 	     error.  */
+ 	  secs = PROFILE_MODEL_TOTAL_CYCLES (data) / clock;
+ 	  secs = ((double) (unsigned long) (secs * 100 + .5)) / 100;
+ 	  sim_io_printf (sd, "  Simulated execution time: %.2f seconds\n",
+ 			 secs);
+ 	}
      }
  }
  
Index: sim/common/sim-profile.h
===================================================================
RCS file: /cvs/src/src/sim/common/sim-profile.h,v
retrieving revision 1.1.1.2
diff -c -p -r1.1.1.2 sim-profile.h
*** sim-profile.h	1999/12/22 21:45:38	1.1.1.2
--- sim-profile.h	2000/07/27 16:43:26
*************** typedef struct {
*** 150,155 ****
--- 150,159 ----
    unsigned long total_insn_count;
  #define PROFILE_TOTAL_INSN_COUNT(p) ((p)->total_insn_count)
  
+   /* CPU frequency.  Always accepted, regardless of profiling options.  */
+   unsigned long cpu_freq;
+ #define PROFILE_CPU_FREQ(p) ((p)->cpu_freq)
+ 
  #if WITH_PROFILE_INSN_P
    unsigned int *insn_count;
  #define PROFILE_INSN_COUNT(p) ((p)->insn_count)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]