これらは, 処理時間を計測するためのユーティリティ・クラス.
((cite: hotspot/src/share/vm/runtime/timer.hpp))
// Timers for simple measurement.
処理時間の簡単な計測処理を行うためのユーティリティ・クラス.
((cite: hotspot/src/share/vm/runtime/timer.hpp))
class elapsedTimer VALUE_OBJ_CLASS_SPEC {
elapsedTimer::start() で計測を開始し, elapsedTimer::stop() で計測を終了する.
終了後は, elapsedTimer::ticks() や elapsedTimer::seconds(), elapsedTimer::milliseconds() で時間を取得できる (それぞれ計測時間を, OS の ticks 単位, 秒単位, ミリ秒単位, で返す).
なお, 計測中に (stop() させずに) それまでの時間を取得するための elapsedTimer::active_ticks() というメソッドもある.
HotSpot 内の様々な箇所で使用されている (#TODO).
現状の実装では os::elapsed_counter() で時間を取得している.
((cite: hotspot/src/share/vm/runtime/timer.cpp))
void elapsedTimer::start() {
if (!_active) {
_active = true;
_start_counter = os::elapsed_counter();
}
}
void elapsedTimer::stop() {
if (_active) {
_counter += os::elapsed_counter() - _start_counter;
_active = false;
}
}
((cite: hotspot/src/share/vm/runtime/timer.hpp))
jlong ticks() const { return _counter; }
((cite: hotspot/src/share/vm/runtime/timer.cpp))
double elapsedTimer::seconds() const {
double count = (double) _counter;
double freq = (double) os::elapsed_frequency();
return count/freq;
}
jlong elapsedTimer::milliseconds() const {
jlong ticks_per_ms = os::elapsed_frequency() / 1000;
return _counter / ticks_per_ms;
}
((cite: hotspot/src/share/vm/runtime/timer.cpp))
jlong elapsedTimer::active_ticks() const {
if (!_active) {
return ticks();
}
jlong counter = _counter + os::elapsed_counter() - _start_counter;
return counter;
}
See: here for details
処理時間の簡単な計測処理を行うためのユーティリティ・クラス.
((cite: hotspot/src/share/vm/runtime/timer.hpp))
// TimeStamp is used for recording when an event took place.
class TimeStamp VALUE_OBJ_CLASS_SPEC {
まず TimeStamp::update() または TimeStamp::update_to() で起点となる時間を設定する (update_to() では起点となる時間を明示的に指定する. update() では現在の時間が起点になる).
その後は, TimeStamp::ticks_since_update(), TimeStamp::seconds(), および TimeStamp::milliseconds() で起点からの経過時間を取得できる (それぞれ経過時間を, OS の ticks 単位, 秒単位, ミリ秒単位, で返す).
起点を変更したくなったら, また TimeStamp::update() や TimeStamp::update_to() を呼べばよい.
HotSpot 内の様々な箇所で使用されている (#TODO).
現状の実装では os::elapsed_counter() で時間を取得している.
((cite: hotspot/src/share/vm/runtime/timer.cpp))
void TimeStamp::update_to(jlong ticks) {
_counter = ticks;
if (_counter == 0) _counter = 1;
assert(is_updated(), "must not look clear");
}
void TimeStamp::update() {
update_to(os::elapsed_counter());
}
((cite: hotspot/src/share/vm/runtime/timer.cpp))
double TimeStamp::seconds() const {
assert(is_updated(), "must not be clear");
jlong new_count = os::elapsed_counter();
double count = (double) new_count - _counter;
double freq = (double) os::elapsed_frequency();
return count/freq;
}
jlong TimeStamp::milliseconds() const {
assert(is_updated(), "must not be clear");
jlong new_count = os::elapsed_counter();
jlong count = new_count - _counter;
jlong ticks_per_ms = os::elapsed_frequency() / 1000;
return count / ticks_per_ms;
}
jlong TimeStamp::ticks_since_update() const {
assert(is_updated(), "must not be clear");
return os::elapsed_counter() - _counter;
}
See: here for details
処理時間の簡単な計測処理を行うためのユーティリティ・クラス(StackObjクラス).
処理時間の計測処理をソースコード上のスコープに合わせて行うことができる (= コンストラクタが呼ばれてからデストラクタが呼ばれるまでの時間を計測する).
計測結果は, 指定された elapsedTimer オブジェクトに足し込まれたり, 指定のログファイル(デフォルトでは tty)に出力される.
((cite: hotspot/src/share/vm/runtime/timer.hpp))
// TraceTime is used for tracing the execution time of a block
// Usage:
// { TraceTime t("block time")
// some_code();
// }
//
class TraceTime: public StackObj {
コード中で TraceTime 型の局所変数を宣言するだけ.
HotSpot 内の様々な箇所で使用されている (#TODO).
内部には elapsedTimer オブジェクトを保持している (現状の実装では elapsedTimer を用いて時間を取得している).
((cite: hotspot/src/share/vm/runtime/timer.hpp))
elapsedTimer _t; // timer
コンストラクタで elapsedTimer::start() を呼んで計測を開始する.
デストラクタで elapsedTimer::stop() で計測を終了する. 計測結果は, 以下の2つの用途に使用される.
(なお, doit コンストラクタ引数が false だった場合(= _active フィールドが false になる場合)は, このオブジェクトによる処理(計測処理/出力処理)は全て省略される)
((cite: hotspot/src/share/vm/runtime/timer.cpp))
TraceTime::TraceTime(const char* title,
bool doit,
bool print_cr,
outputStream* logfile) {
_active = doit;
_verbose = true;
_print_cr = print_cr;
_logfile = (logfile != NULL) ? logfile : tty;
if (_active) {
_accum = NULL;
if (PrintGCTimeStamps) {
_logfile->stamp();
_logfile->print(": ");
}
_logfile->print("[%s", title);
_logfile->flush();
_t.start();
}
}
TraceTime::TraceTime(const char* title,
elapsedTimer* accumulator,
bool doit,
bool verbose,
outputStream* logfile) {
_active = doit;
_verbose = verbose;
_print_cr = true;
_logfile = (logfile != NULL) ? logfile : tty;
if (_active) {
if (_verbose) {
if (PrintGCTimeStamps) {
_logfile->stamp();
_logfile->print(": ");
}
_logfile->print("[%s", title);
_logfile->flush();
}
_accum = accumulator;
_t.start();
}
}
TraceTime::~TraceTime() {
if (_active) {
_t.stop();
if (_accum!=NULL) _accum->add(_t);
if (_verbose) {
if (_print_cr) {
_logfile->print_cr(", %3.7f secs]", _t.seconds());
} else {
_logfile->print(", %3.7f secs]", _t.seconds());
}
_logfile->flush();
}
}
}
なお, 一時的にタイマーを止めたり再会させたりすることもできる模様.
((cite: hotspot/src/share/vm/runtime/timer.hpp))
// Activation
void suspend() { if (_active) _t.stop(); }
void resume() { if (_active) _t.start(); }
See: here for details
処理時間の簡単な計測処理を行うためのユーティリティ・クラス(StackObjクラス).
処理時間の計測処理をソースコード上のスコープに合わせて行うことができる (= コンストラクタが呼ばれてからデストラクタが呼ばれるまでの時間を計測する).
計測結果は, 指定されたログファイル(デフォルトでは tty)に出力される.
((cite: hotspot/src/share/vm/runtime/timer.hpp))
class TraceCPUTime: public StackObj {
コード中で TraceCPUTime 型の局所変数を宣言するだけ.
HotSpot 内の様々な箇所で使用されている (#TODO).
なお, 現在は PrintGCDetails オプションが指定されている場合にのみ有効になる模様 (全ての使用箇所で doit コンストラクタ引数として PrintGCDetails オプションの値が使用されているので).
コンストラクタで os::getTimesSecs() を呼んで計測を開始する.
デストラクタで os::getTimesSecs() で計測を終了し, コンストラクタ引数で指定された outputStream (指定が無ければ tty) に出力する.
(なお, doit コンストラクタ引数が false だった場合(= _active フィールドが false になる場合)は, このオブジェクトによる処理(計測処理/出力処理)は全て省略される)
((cite: hotspot/src/share/vm/runtime/timer.cpp))
TraceCPUTime::TraceCPUTime(bool doit,
bool print_cr,
outputStream *logfile) :
_active(doit),
_print_cr(print_cr),
_starting_user_time(0.0),
_starting_system_time(0.0),
_starting_real_time(0.0),
_logfile(logfile),
_error(false) {
if (_active) {
if (logfile != NULL) {
_logfile = logfile;
} else {
_logfile = tty;
}
_error = !os::getTimesSecs(&_starting_real_time,
&_starting_user_time,
&_starting_system_time);
}
}
TraceCPUTime::~TraceCPUTime() {
if (_active) {
bool valid = false;
if (!_error) {
double real_secs; // walk clock time
double system_secs; // system time
double user_secs; // user time for all threads
double real_time, user_time, system_time;
valid = os::getTimesSecs(&real_time, &user_time, &system_time);
if (valid) {
user_secs = user_time - _starting_user_time;
system_secs = system_time - _starting_system_time;
real_secs = real_time - _starting_real_time;
_logfile->print(" [Times: user=%3.2f sys=%3.2f, real=%3.2f secs] ",
user_secs, system_secs, real_secs);
} else {
_logfile->print("[Invalid result in TraceCPUTime]");
}
} else {
_logfile->print("[Error in TraceCPUTime]");
}
if (_print_cr) {
_logfile->print_cr("");
}
}
}
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.