[patch][commit] More --gprof Fixes

Dave Brolley <[email protected]>
Newsgroups gmane.comp.emulators.sid.devel
Message-ID <[email protected]>
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
sid-gprof.ChangeLog (text/plain, 486 B)
2006-06-20  Dave Brolley  <[email protected]>

	* 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.
sid-gprof.patch.txt (text/plain, 6.3 KB)
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)
        {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.