[gold patch] Add timers for each pass
Cary Coutant
ccoutant@google.com
Fri Oct 14 23:51:00 GMT 2011
Ian,
This patch adds separate timers for each of the three linker passes
(initial, middle, final). I find them useful for investigating (at a
coarse level) where --threads is helping.
It doesn't necessarily need to get checked in, but I thought I'd ask
if you think it could be generally useful.
For links out of tmpfs, it turns out that the entire speed up due to
multi-threading is in pass 3.
-cary
* gold/gold.cc: Include timer.h.
(queue_middle_tasks): Stamp time.
(queue_final_tasks): Likewise.
* gold/main.cc (main): Store timer in parameters. Print timers
for each pass.
* gold/parameters.cc (Parameters::Parameters): Initialize timer_.
(Parameters::set_timer): New function.
(set_parameters_timer): New function.
* gold/parameters.h (Parameters::set_timer): New function.
(Parameters::timer): New function.
(Parameters::timer_): New data member.
(set_parameters_timer): New function.
* gold/timer.cc (Timer::stamp): New function.
(Timer::get_pass_time): New function.
* gold/timer.h (Timer::stamp): New function.
(Timer::get_pass_time): New function.
(Timer::pass_times_): New data member.
-------------- next part --------------
2011-10-14 Cary Coutant <ccoutant@google.com>
* gold/gold.cc: Include timer.h.
(queue_middle_tasks): Stamp time.
(queue_final_tasks): Likewise.
* gold/main.cc (main): Store timer in parameters. Print timers
for each pass.
* gold/parameters.cc (Parameters::Parameters): Initialize timer_.
(Parameters::set_timer): New function.
(set_parameters_timer): New function.
* gold/parameters.h (Parameters::set_timer): New function.
(Parameters::timer): New function.
(Parameters::timer_): New data member.
(set_parameters_timer): New function.
* gold/timer.cc (Timer::stamp): New function.
(Timer::get_pass_time): New function.
* gold/timer.h (Timer::stamp): New function.
(Timer::get_pass_time): New function.
(Timer::pass_times_): New data member.
commit dae0443e4de4facc7d9a22e36bdf6845932cfa32
Author: Cary Coutant <ccoutant@google.com>
Date: Fri Oct 14 16:40:00 2011 -0700
Add per-pass timers for --stats output.
diff --git a/gold/gold.cc b/gold/gold.cc
index 2700bdb..f455ec8 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -45,6 +45,7 @@
#include "gc.h"
#include "icf.h"
#include "incremental.h"
+#include "timer.h"
namespace gold
{
@@ -487,6 +488,10 @@ queue_middle_tasks(const General_options& options,
Workqueue* workqueue,
Mapfile* mapfile)
{
+ Timer* timer = parameters->timer();
+ if (timer != NULL)
+ timer->stamp(0);
+
// Add any symbols named with -u options to the symbol table.
symtab->add_undefined_symbols_from_command_line(layout);
@@ -786,6 +791,10 @@ queue_final_tasks(const General_options& options,
Workqueue* workqueue,
Output_file* of)
{
+ Timer* timer = parameters->timer();
+ if (timer != NULL)
+ timer->stamp(1);
+
int thread_count = options.thread_count_final();
if (thread_count == 0)
thread_count = std::max(2, input_objects->number_of_input_objects());
diff --git a/gold/main.cc b/gold/main.cc
index f6e7609..97a6616 100644
--- a/gold/main.cc
+++ b/gold/main.cc
@@ -165,7 +165,10 @@ main(int argc, char** argv)
Timer timer;
if (command_line.options().stats())
- timer.start();
+ {
+ timer.start();
+ set_parameters_timer(&timer);
+ }
// Store some options in the globally accessible parameters.
set_parameters_options(&command_line.options());
@@ -252,7 +255,32 @@ main(int argc, char** argv)
if (command_line.options().stats())
{
- Timer::TimeStats elapsed = timer.get_elapsed_time();
+ timer.stamp(2);
+ Timer::TimeStats elapsed = timer.get_pass_time(0);
+ fprintf(stderr,
+ _("%s: pass 1 run time: " \
+ "(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)\n"),
+ program_name,
+ elapsed.user / 1000, (elapsed.user % 1000) * 1000,
+ elapsed.sys / 1000, (elapsed.sys % 1000) * 1000,
+ elapsed.wall / 1000, (elapsed.wall % 1000) * 1000);
+ elapsed = timer.get_pass_time(1);
+ fprintf(stderr,
+ _("%s: pass 2 run time: " \
+ "(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)\n"),
+ program_name,
+ elapsed.user / 1000, (elapsed.user % 1000) * 1000,
+ elapsed.sys / 1000, (elapsed.sys % 1000) * 1000,
+ elapsed.wall / 1000, (elapsed.wall % 1000) * 1000);
+ elapsed = timer.get_pass_time(2);
+ fprintf(stderr,
+ _("%s: pass 3 run time: " \
+ "(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)\n"),
+ program_name,
+ elapsed.user / 1000, (elapsed.user % 1000) * 1000,
+ elapsed.sys / 1000, (elapsed.sys % 1000) * 1000,
+ elapsed.wall / 1000, (elapsed.wall % 1000) * 1000);
+ elapsed = timer.get_elapsed_time();
fprintf(stderr,
_("%s: total run time: " \
"(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)\n"),
diff --git a/gold/parameters.cc b/gold/parameters.cc
index c14bd1e..7fc5730 100644
--- a/gold/parameters.cc
+++ b/gold/parameters.cc
@@ -64,7 +64,7 @@ Set_parameters_target_once set_parameters_target_once(&static_parameters);
// Class Parameters.
Parameters::Parameters()
- : errors_(NULL), options_(NULL), target_(NULL),
+ : errors_(NULL), timer_(NULL), options_(NULL), target_(NULL),
doing_static_link_valid_(false), doing_static_link_(false),
debug_(0), incremental_mode_(General_options::INCREMENTAL_OFF),
set_parameters_target_once_(&set_parameters_target_once)
@@ -79,6 +79,13 @@ Parameters::set_errors(Errors* errors)
}
void
+Parameters::set_timer(Timer* timer)
+{
+ gold_assert(this->timer_ == NULL);
+ this->timer_ = timer;
+}
+
+void
Parameters::set_options(const General_options* options)
{
gold_assert(!this->options_valid());
@@ -270,6 +277,10 @@ set_parameters_errors(Errors* errors)
{ static_parameters.set_errors(errors); }
void
+set_parameters_timer(Timer* timer)
+{ static_parameters.set_timer(timer); }
+
+void
set_parameters_options(const General_options* options)
{ static_parameters.set_options(options); }
diff --git a/gold/parameters.h b/gold/parameters.h
index 09b0516..10de2ae 100644
--- a/gold/parameters.h
+++ b/gold/parameters.h
@@ -28,6 +28,7 @@ namespace gold
class General_options;
class Errors;
+class Timer;
class Target;
template<int size, bool big_endian>
class Sized_target;
@@ -57,6 +58,9 @@ class Parameters
set_errors(Errors* errors);
void
+ set_timer(Timer* timer);
+
+ void
set_options(const General_options* options);
void
@@ -70,6 +74,11 @@ class Parameters
errors() const
{ return this->errors_; }
+ // Return the timer object.
+ Timer*
+ timer() const
+ { return this->timer_; }
+
// Whether the options are valid. This should not normally be
// called, but it is needed by gold_exit.
bool
@@ -177,6 +186,7 @@ class Parameters
friend class Set_parameters_target_once;
Errors* errors_;
+ Timer* timer_;
const General_options* options_;
Target* target_;
bool doing_static_link_valid_;
@@ -196,6 +206,9 @@ extern void
set_parameters_errors(Errors* errors);
extern void
+set_parameters_timer(Timer* timer);
+
+extern void
set_parameters_options(const General_options* options);
extern void
diff --git a/gold/timer.cc b/gold/timer.cc
index d9b8874..1423663 100644
--- a/gold/timer.cc
+++ b/gold/timer.cc
@@ -49,6 +49,15 @@ Timer::start()
this->get_time(&this->start_time_);
}
+// Record the time used by pass N (0 <= N <= 2).
+void
+Timer::stamp(int n)
+{
+ gold_assert(n >= 0 && n <= 2);
+ TimeStats& thispass = this->pass_times_[n];
+ this->get_time(&thispass);
+}
+
#if HAVE_SYSCONF && defined _SC_CLK_TCK
# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
#else
@@ -106,4 +115,17 @@ Timer::get_elapsed_time()
return delta;
}
+// Return the stats for pass N (0 <= N <= 2).
+Timer::TimeStats
+Timer::get_pass_time(int n)
+{
+ gold_assert(n >= 0 && n <= 2);
+ TimeStats thispass = this->pass_times_[n];
+ TimeStats& lastpass = n > 0 ? this->pass_times_[n-1] : this->start_time_;
+ thispass.wall -= lastpass.wall;
+ thispass.user -= lastpass.user;
+ thispass.sys -= lastpass.sys;
+ return thispass;
+}
+
}
diff --git a/gold/timer.h b/gold/timer.h
index 50b55e4..339aef1 100644
--- a/gold/timer.h
+++ b/gold/timer.h
@@ -23,6 +23,8 @@
#ifndef GOLD_TIMER_H
#define GOLD_TIMER_H
+#include <vector>
+
namespace gold
{
@@ -48,10 +50,18 @@ class Timer
TimeStats
get_elapsed_time();
+ // Return the stats for pass N (0 <= N <= 2).
+ TimeStats
+ get_pass_time(int n);
+
// Start counting the time.
void
start();
+ // Record the time used by pass N (0 <= N <= 2).
+ void
+ stamp(int n);
+
private:
// This class cannot be copied.
Timer(const Timer&);
@@ -63,6 +73,9 @@ class Timer
// The time of the last call to start.
TimeStats start_time_;
+
+ // Times for each pass.
+ TimeStats pass_times_[3];
};
}
More information about the Binutils
mailing list