[patch][commit] More --gprof Fixes

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[patch][commit] More --gprof Fixes

Dave Brolley-2
Hi,

I've committed the attached patch which addresses a problem encountered
on architectures with parallel insn execution.

CGEN cpus in SID compute total cycles used by adding total_insn_count +
total_latency. In the case of parallel execution, total_latency may
actually decrease since, for a parallel insn, total_insn_count
increases, but the number of cycles used does not.

The sample_gprof method I committed in my previous patch was using
total_latency to determine how many samples to take. I have now changed
it to use total_insn_count + current_step_insn_count + total_latency to
compute this.

The patch also corrects the resetting of gprof_prev_cycle so that it
does not get reset unless gprof has been turned off dynamically. This
allows initial latency for a cpu to be counted properly.

Dave

2006-06-20  Dave Brolley  <[hidden email]>

        * sidcpuutil.h (basic_cpu): Remove gprof_prev_latency. Add
        gprof_prev_cycle, gprof_unconfigured_p.
        (sample_gprof): Now takes bool argument. Compute number of samples
        based on total_insn_count + current_step_insn_count + total_latency.
        (unconfigure_gprof): Set gprof_unconfigured_p.
        (configure_gprof): Only reset gprof_pref_cycle if gprof_unconfigured_p
        is true.
        (configure): When configuring --insn-count reset gprof_prev_cycle.


Index: sid/include/sidcpuutil.h
===================================================================
RCS file: /cvs/src/src/sid/include/sidcpuutil.h,v
retrieving revision 1.36
diff -c -p -r1.36 sidcpuutil.h
*** sid/include/sidcpuutil.h 14 Jun 2006 20:39:31 -0000 1.36
--- sid/include/sidcpuutil.h 20 Jun 2006 18:07:03 -0000
*************** namespace sidutil
*** 322,329 ****
  if (! this->yield_p)
   {
     if (UNLIKELY (this->gprof_configured_p))
!      this->sample_gprof (1);
!    this->gprof_prev_latency = this->total_latency;
     this->step_insns ();
   }
  sid::host_int_8 num_insns = this->total_insn_count - prev_insn_count;
--- 322,328 ----
  if (! this->yield_p)
   {
     if (UNLIKELY (this->gprof_configured_p))
!      this->sample_gprof (true);
     this->step_insns ();
   }
  sid::host_int_8 num_insns = this->total_insn_count - prev_insn_count;
*************** namespace sidutil
*** 397,427 ****
        return num;
      }
 
!     void sample_gprof (sid::host_int_4 num_insns)
      {
!       this->gprof_counter += num_insns;
 
-       // Sample for gprof in insn-count mode?
        if (this->gprof_cycles == 0)
  {
   sid::host_int_4 ticks = this->gprof_counter / this->step_insn_count;
   if (ticks > 0)
     {
       this->sample_gprof_pin.drive (ticks);
       this->gprof_counter %= this->step_insn_count;
     }
-  return;
  }
!
!       // Sample for gprof in cycle mode
!       if ((sid::signed_host_int_8)(this->total_latency) > (sid::signed_host_int_8)(this->gprof_prev_latency))
! this->gprof_counter += this->total_latency - this->gprof_prev_latency;
!
!       sid::host_int_4 ticks = this->gprof_counter / this->gprof_cycles;
!       if (ticks > 0)
  {
!  this->sample_gprof_pin.drive (ticks);
!  this->gprof_counter %= this->gprof_cycles;
  }
      }
 
--- 396,441 ----
        return num;
      }
 
!     void sample_gprof (bool before)
      {
!       // What is the current cycle/insn? Always count insns.
!       sid::host_int_8 current_cycle = this->total_insn_count + this->current_step_insn_count;
!
!       // If called before the insn execution loop, then the current insn
!       // hasn't been counted yet.
!       if (before)
! ++current_cycle;
!
!       // Count total_latency if we're in cycle mode.
!       if (this->gprof_cycles != 0)
! current_cycle += this->total_latency;
!
!       // Have we advanced?
!       if (current_cycle <= this->gprof_prev_cycle)
! return;
!
!       gprof_counter += current_cycle - this->gprof_prev_cycle;
!       this->gprof_prev_cycle = current_cycle;
 
        if (this->gprof_cycles == 0)
  {
+  // Sample for gprof in insn-count mode.
   sid::host_int_4 ticks = this->gprof_counter / this->step_insn_count;
   if (ticks > 0)
     {
       this->sample_gprof_pin.drive (ticks);
       this->gprof_counter %= this->step_insn_count;
     }
  }
!       else
  {
!  // Sample for gprof in cycle mode.
!  sid::host_int_4 ticks = this->gprof_counter / this->gprof_cycles;
!  if (ticks > 0)
!    {
!      this->sample_gprof_pin.drive (ticks);
!      this->gprof_counter %= this->gprof_cycles;
!    }
  }
      }
 
*************** namespace sidutil
*** 445,457 ****
 
  // Sample for gprof?
  if (UNLIKELY (this->gprof_configured_p))
!  {
!    // Count 1 fewer insns if exiting to account for the one counted on entry
!    if (rc)
!      --num;
!    this->sample_gprof (num);
!  }
! this->gprof_prev_latency = this->total_latency;
 
  return rc;
        }
--- 459,465 ----
 
  // Sample for gprof?
  if (UNLIKELY (this->gprof_configured_p))
!  this->sample_gprof (false);
 
  return rc;
        }
*************** namespace sidutil
*** 534,539 ****
--- 542,548 ----
 
      void unconfigure_gprof ()
        {
+ gprof_unconfigured_p = true;
  if (! gprof_configured_p)
   return;
 
*************** namespace sidutil
*** 576,591 ****
--- 585,607 ----
  if (p)
   sample_gprof_pin.connect (p);
 
+ // Set the state so that the next insn will be sampled, followed by
+ // samples at the specified interval. Reset gprof_prev_cycle only
+ // if gprof has been unconfigured at some point.
  vector<string> parts = tokenize (config.substr (6), ",");
  if (parts.size () == 2)
   {
     component::status s = parse_attribute (parts[1], gprof_cycles);
     gprof_counter = gprof_cycles - 1;
+    if (gprof_unconfigured_p)
+      gprof_prev_cycle = this->total_insn_count + this->total_latency;
   }
  else
   {
     gprof_cycles = 0;
     gprof_counter = step_insn_count - 1;
+    if (gprof_unconfigured_p)
+      gprof_prev_cycle = this->total_insn_count;
   }
 
  gprof_configured_p = true;
*************** namespace sidutil
*** 600,608 ****
      sid::host_int_4 last_caller;
      sid::host_int_4 last_callee;
      bool gprof_configured_p;
      sid::host_int_4 gprof_cycles;
      sid::host_int_4 gprof_counter;
!     sid::host_int_8 gprof_prev_latency;
 
      virtual void configure (const string &config)
        {
--- 616,625 ----
      sid::host_int_4 last_caller;
      sid::host_int_4 last_callee;
      bool gprof_configured_p;
+     bool gprof_unconfigured_p;
      sid::host_int_4 gprof_cycles;
      sid::host_int_4 gprof_counter;
!     sid::host_int_8 gprof_prev_cycle;
 
      virtual void configure (const string &config)
        {
*************** namespace sidutil
*** 635,641 ****
       {
  step_insn_count = n;
  if (gprof_configured_p && gprof_cycles == 0)
!  gprof_counter = step_insn_count - 1;
       }
     return;
   }
--- 652,663 ----
       {
  step_insn_count = n;
  if (gprof_configured_p && gprof_cycles == 0)
!  {
!    // Set the state so that the next insn will be sampled,
!    // followed by samples at the specified interval.
!    gprof_counter = step_insn_count - 1;
!    gprof_prev_cycle = this->total_insn_count - 1;
!  }
       }
     return;
   }
*************** public:
*** 902,908 ****
        last_caller (0),
        last_callee (0),
        gprof_configured_p (false),
!       gprof_prev_latency (0),
        core_probe (0),
        main (0)
        {
--- 924,931 ----
        last_caller (0),
        last_callee (0),
        gprof_configured_p (false),
!       gprof_unconfigured_p (false),
!       gprof_prev_cycle (0),
        core_probe (0),
        main (0)
        {