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