This is the mail archive of the sid@sourceware.org mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch][commit] More --gprof Fixes


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  <brolley@redhat.com>

	* 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)
        {

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