This is the mail archive of the
sid@sourceware.org
mailing list for the SID project.
[patch][commit] More --gprof Fixes
- From: Dave Brolley <brolley at redhat dot com>
- To: sid at sources dot redhat dot com
- Date: Tue, 20 Jun 2006 14:20:09 -0400
- Subject: [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)
{