src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jul 19 10:34:07 2012
--- new/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jul 19 10:34:06 2012
*** 77,107 ****
--- 77,175 ----
gclog_or_tty->print_cr("%s", _buffer);
_cur = _indent_level * INDENT_CHARS;
}
};
+ template <class T>
+ void WorkerDataArray<T>::print(int level, const char* title) {
+ if (_length == 1) {
+ // No need for min, max, average and sum for only one worker
+ LineBuffer buf(level);
+ buf.append("[%s: ", title);
+ buf.append(_print_format, _data[0]);
+ buf.append_and_print_cr("]");
+ return;
+ }
+
+ T min = _data[0];
+ T max = _data[0];
+ T sum = 0;
+
+ LineBuffer buf(level);
+ buf.append("[%s:", title);
+ for (uint i = 0; i < _length; ++i) {
+ T val = _data[i];
+ min = MIN2(val, min);
+ max = MAX2(val, max);
+ sum += val;
+ if (G1Log::finest()) {
+ buf.append(" ");
+ buf.append(_print_format, val);
+ }
+ }
+
+ if (G1Log::finest()) {
+ buf.append_and_print_cr("");
+ }
+
+ double avg = (double)sum / (double)_length;
+ buf.append(" Min: ");
+ buf.append(_print_format, min);
+ buf.append(", Avg: ");
+ buf.append("%.1lf", avg); // Always print average as a double
+ buf.append(", Max: ");
+ buf.append(_print_format, max);
+ buf.append(", Diff: ");
+ buf.append(_print_format, max - min);
+ if (_print_sum) {
+ // for things like the start and end times the sum is not
+ // that relevant
+ buf.append(", Sum: ");
+ buf.append(_print_format, sum);
+ }
+ buf.append_and_print_cr("]");
+ }
+
+ #ifdef ASSERT
+
+ template <class T>
+ void WorkerDataArray<T>::reset() {
+ for (uint i = 0; i < _length; i++) {
+ _data[i] = (T)-1;
+ }
+ }
+
+ template <class T>
+ void WorkerDataArray<T>::verify() {
+ for (uint i = 0; i < _length; i++) {
+ assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i));
+ }
+ }
+
+ #endif
+
G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
_max_gc_threads(max_gc_threads),
_min_clear_cc_time_ms(-1.0),
_max_clear_cc_time_ms(-1.0),
_cur_clear_cc_time_ms(0.0),
_cum_clear_cc_time_ms(0.0),
! _num_cc_clears(0L),
+ _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
+ _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+ _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
+ _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
+ _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
+ _last_termination_times_ms(_max_gc_threads, "%.1lf"),
+ _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
+ _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
+ _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
+ _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf")
{
assert(max_gc_threads > 0, "Must have some GC threads");
_par_last_gc_worker_start_times_ms = new double[_max_gc_threads];
_par_last_ext_root_scan_times_ms = new double[_max_gc_threads];
_par_last_satb_filtering_times_ms = new double[_max_gc_threads];
_par_last_update_rs_times_ms = new double[_max_gc_threads];
_par_last_update_rs_processed_buffers = new double[_max_gc_threads];
_par_last_scan_rs_times_ms = new double[_max_gc_threads];
_par_last_obj_copy_times_ms = new double[_max_gc_threads];
_par_last_termination_times_ms = new double[_max_gc_threads];
_par_last_termination_attempts = new double[_max_gc_threads];
_par_last_gc_worker_end_times_ms = new double[_max_gc_threads];
_par_last_gc_worker_times_ms = new double[_max_gc_threads];
_par_last_gc_worker_other_times_ms = new double[_max_gc_threads];
}
void G1GCPhaseTimes::note_gc_start(double pause_start_time_sec, uint active_gc_threads,
bool is_young_gc, bool is_initial_mark_gc, GCCause::Cause gc_cause) {
assert(active_gc_threads > 0, "The number of threads must be > 0");
*** 110,276 ****
--- 178,247 ----
_pause_start_time_sec = pause_start_time_sec;
_is_young_gc = is_young_gc;
_is_initial_mark_gc = is_initial_mark_gc;
_gc_cause = gc_cause;
#ifdef ASSERT
// initialise the timing data to something well known so that we can spot
// if something is not set properly
for (uint i = 0; i < _max_gc_threads; ++i) {
! _par_last_gc_worker_start_times_ms[i] = -1234.0;
! _par_last_ext_root_scan_times_ms[i] = -1234.0;
! _par_last_satb_filtering_times_ms[i] = -1234.0;
! _par_last_update_rs_times_ms[i] = -1234.0;
! _par_last_update_rs_processed_buffers[i] = -1234.0;
! _par_last_scan_rs_times_ms[i] = -1234.0;
! _par_last_obj_copy_times_ms[i] = -1234.0;
_par_last_termination_times_ms[i] = -1234.0;
_par_last_termination_attempts[i] = -1234.0;
_par_last_gc_worker_end_times_ms[i] = -1234.0;
_par_last_gc_worker_times_ms[i] = -1234.0;
_par_last_gc_worker_other_times_ms[i] = -1234.0;
}
#endif
+ _last_gc_worker_start_times_ms.reset();
+ _last_ext_root_scan_times_ms.reset();
+ _last_satb_filtering_times_ms.reset();
+ _last_update_rs_times_ms.reset();
+ _last_update_rs_processed_buffers.reset();
! _last_scan_rs_times_ms.reset();
! _last_obj_copy_times_ms.reset();
! _last_termination_times_ms.reset();
! _last_termination_attempts.reset();
! _last_gc_worker_end_times_ms.reset();
! _last_gc_worker_times_ms.reset();
! _last_gc_worker_other_times_ms.reset();
}
void G1GCPhaseTimes::note_gc_end(double pause_end_time_sec) {
+ _last_gc_worker_start_times_ms.verify();
+ _last_ext_root_scan_times_ms.verify();
+ _last_satb_filtering_times_ms.verify();
+ _last_update_rs_times_ms.verify();
+ _last_update_rs_processed_buffers.verify();
+ _last_scan_rs_times_ms.verify();
+ _last_obj_copy_times_ms.verify();
+ _last_termination_times_ms.verify();
+ _last_termination_attempts.verify();
+ _last_gc_worker_end_times_ms.verify();
+
if (G1Log::fine()) {
double pause_time_ms = (pause_end_time_sec - _pause_start_time_sec) * MILLIUNITS;
for (uint i = 0; i < _active_gc_threads; i++) {
_par_last_gc_worker_times_ms[i] = _par_last_gc_worker_end_times_ms[i] -
! _par_last_gc_worker_start_times_ms[i];
+ _last_gc_worker_times_ms.set(i,
! _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i));
! double worker_known_time = _par_last_ext_root_scan_times_ms[i] +
! _par_last_satb_filtering_times_ms[i] +
! _par_last_update_rs_times_ms[i] +
! _par_last_scan_rs_times_ms[i] +
! _par_last_obj_copy_times_ms[i] +
! _par_last_termination_times_ms[i];
! double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
! _last_satb_filtering_times_ms.get(i) +
! _last_update_rs_times_ms.get(i) +
! _last_scan_rs_times_ms.get(i) +
! _last_obj_copy_times_ms.get(i) +
! _last_termination_times_ms.get(i);
_par_last_gc_worker_other_times_ms[i] = _par_last_gc_worker_times_ms[i] -
! _last_gc_worker_times_ms.get(i) - worker_known_time);
+ _last_gc_worker_other_times_ms.set(i,
}
! print(pause_time_ms);
}
! _last_gc_worker_times_ms.verify();
+ _last_gc_worker_other_times_ms.verify();
}
void G1GCPhaseTimes::print_par_stats(int level,
const char* str,
double* data,
bool showDecimals) {
double min = data[0], max = data[0];
double total = 0.0;
LineBuffer buf(level);
buf.append("[%s (ms):", str);
for (uint i = 0; i < _active_gc_threads; ++i) {
double val = data[i];
if (val < min)
min = val;
if (val > max)
max = val;
total += val;
if (G1Log::finest()) {
if (showDecimals) {
buf.append(" %.1lf", val);
} else {
buf.append(" %d", (int)val);
}
}
+ print(pause_time_ms);
}
if (G1Log::finest()) {
buf.append_and_print_cr("");
}
double avg = total / (double) _active_gc_threads;
if (showDecimals) {
buf.append_and_print_cr(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf, Sum: %.1lf]",
min, avg, max, max - min, total);
} else {
buf.append_and_print_cr(" Min: %d, Avg: %d, Max: %d, Diff: %d, Sum: %d]",
(int)min, (int)avg, (int)max, (int)max - (int)min, (int)total);
}
}
void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
}
void G1GCPhaseTimes::print_stats(int level, const char* str, double value, int workers) {
LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
}
void G1GCPhaseTimes::print_stats(int level, const char* str, int value) {
LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
}
double G1GCPhaseTimes::avg_value(double* data) {
if (G1CollectedHeap::use_parallel_gc_threads()) {
double ret = 0.0;
for (uint i = 0; i < _active_gc_threads; ++i) {
ret += data[i];
}
return ret / (double) _active_gc_threads;
} else {
return data[0];
}
}
double G1GCPhaseTimes::max_value(double* data) {
if (G1CollectedHeap::use_parallel_gc_threads()) {
double ret = data[0];
for (uint i = 1; i < _active_gc_threads; ++i) {
if (data[i] > ret) {
ret = data[i];
}
}
return ret;
} else {
return data[0];
}
}
double G1GCPhaseTimes::sum_of_values(double* data) {
if (G1CollectedHeap::use_parallel_gc_threads()) {
double sum = 0.0;
for (uint i = 0; i < _active_gc_threads; i++) {
sum += data[i];
}
return sum;
} else {
return data[0];
}
}
double G1GCPhaseTimes::max_sum(double* data1, double* data2) {
double ret = data1[0] + data2[0];
if (G1CollectedHeap::use_parallel_gc_threads()) {
for (uint i = 1; i < _active_gc_threads; ++i) {
double data = data1[i] + data2[i];
if (data > ret) {
ret = data;
}
}
}
return ret;
}
void G1GCPhaseTimes::collapse_par_times() {
_ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
_satb_filtering_time = avg_value(_par_last_satb_filtering_times_ms);
_update_rs_time = avg_value(_par_last_update_rs_times_ms);
_update_rs_processed_buffers =
sum_of_values(_par_last_update_rs_processed_buffers);
_scan_rs_time = avg_value(_par_last_scan_rs_times_ms);
_obj_copy_time = avg_value(_par_last_obj_copy_times_ms);
_termination_time = avg_value(_par_last_termination_times_ms);
}
double G1GCPhaseTimes::accounted_time_ms() {
// Subtract the root region scanning wait time. It's initialized to
// zero at the start of the pause.
double misc_time_ms = _root_region_scan_wait_time_ms;
*** 305,345 ****
--- 276,314 ----
if (_root_region_scan_wait_time_ms > 0.0) {
print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
}
if (G1CollectedHeap::use_parallel_gc_threads()) {
print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
! print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
! print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
! if (_satb_filtering_time > 0.0) {
! print_par_stats(2, "SATB Filtering", _par_last_satb_filtering_times_ms);
! _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
! _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
! if (_last_satb_filtering_times_ms.sum() > 0.0) {
! _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
}
! print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
! _last_update_rs_times_ms.print(2, "Update RS (ms)");
if (G1Log::finest()) {
print_par_stats(3, "Processed Buffers", _par_last_update_rs_processed_buffers,
false /* showDecimals */);
+ _last_update_rs_processed_buffers.print(3, "Processed Buffers");
}
! print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
! print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
! print_par_stats(2, "Termination", _par_last_termination_times_ms);
! _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
! _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
! _last_termination_times_ms.print(2, "Termination (ms)");
if (G1Log::finest()) {
print_par_stats(3, "Termination Attempts", _par_last_termination_attempts,
false /* showDecimals */);
+ _last_termination_attempts.print(3, "Termination Attempts");
}
! print_par_stats(2, "GC Worker Other", _par_last_gc_worker_other_times_ms);
! print_par_stats(2, "GC Worker Total", _par_last_gc_worker_times_ms);
! print_par_stats(2, "GC Worker End", _par_last_gc_worker_end_times_ms);
! _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
! _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
! _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
} else {
! print_stats(1, "Ext Root Scanning", _ext_root_scan_time);
! if (_satb_filtering_time > 0.0) {
! print_stats(1, "SATB Filtering", _satb_filtering_time);
! _last_ext_root_scan_times_ms.print(1, "Ext Root Scanning (ms)");
! if (_last_satb_filtering_times_ms.sum() > 0.0) {
! _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
}
! print_stats(1, "Update RS", _update_rs_time);
! _last_update_rs_times_ms.print(1, "Update RS (ms)");
if (G1Log::finest()) {
! print_stats(2, "Processed Buffers", (int)_update_rs_processed_buffers);
! _last_update_rs_processed_buffers.print(2, "Processed Buffers");
}
! print_stats(1, "Scan RS", _scan_rs_time);
! print_stats(1, "Object Copying", _obj_copy_time);
! _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
! _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
}
print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
if (Verbose && G1Log::finest()) {
print_stats(1, "Cur Clear CC", _cur_clear_cc_time_ms);
src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File