diff options
author | Yabin Cui <yabinc@google.com> | 2016-05-16 20:07:26 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2016-05-16 20:07:26 -0700 |
commit | 810d1c5bad205f104e97de252ae4d1bcb7ab4b24 (patch) | |
tree | f5cc5da2b39c0a4d9d00b2143aef73de8e19280f /simpleperf/cmd_stat.cpp | |
parent | b1b964214babaddd0f0bd758c54f7fac4fbe4bf7 (diff) | |
download | extras-810d1c5bad205f104e97de252ae4d1bcb7ab4b24.tar.gz |
simpleperf: fix stat scale output.
Currently simpleperf stat command create an event file for each cpu and
scale the result by summarizing counters on each cpu. But one thread only
runs on one cpu at a time, so it results in wrongly scaled numbers.
Fix this by three changes:
1. For non system-wide stat, Create only one event file for all cpus.
2. When summarizing counters, omit counters having 0 running time.
3. Print real value instead of scaled value.
Run command:
$simpleperf stat ./empty_program
Before the change:
Performance counter statistics:
33,540,176 cpu-cycles # 54.812986 GHz (2%)
28,233,348 stalled-cycles-frontend # 46.140 G/sec (2%)
After the change:
Performance counter statistics:
625,335 cpu-cycles # 1.404496 GHz (100%)
507,200 stalled-cycles-frontend # 1.139 G/sec (100%)
Change-Id: I76bc3e220df4f149ab365e960295b24fde8ae2fc
Diffstat (limited to 'simpleperf/cmd_stat.cpp')
-rw-r--r-- | simpleperf/cmd_stat.cpp | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp index 228b4edc..f477abfd 100644 --- a/simpleperf/cmd_stat.cpp +++ b/simpleperf/cmd_stat.cpp @@ -139,6 +139,9 @@ bool StatCommand::Run(const std::vector<std::string>& args) { return false; } } else { + if (cpus_.empty()) { + cpus_ = {-1}; + } if (!event_selection_set_.OpenEventFilesForThreadsOnCpus(monitored_threads_, cpus_)) { return false; } @@ -365,23 +368,21 @@ bool StatCommand::ShowCounters(const std::vector<CountersInfo>& counters, double uint64_t time_enabled_sum = 0; uint64_t time_running_sum = 0; for (auto& counter_info : counters_info.counters) { - value_sum += counter_info.counter.value; - time_enabled_sum += counter_info.counter.time_enabled; - time_running_sum += counter_info.counter.time_running; + // If time_running is 0, the program has never run on this event and we shouldn't + // summarize it. + if (counter_info.counter.time_running != 0) { + value_sum += counter_info.counter.value; + time_enabled_sum += counter_info.counter.time_enabled; + time_running_sum += counter_info.counter.time_running; + } } double scale = 1.0; - uint64_t scaled_count = value_sum; - if (time_running_sum < time_enabled_sum) { - if (time_running_sum == 0) { - scaled_count = 0; - } else { - scale = static_cast<double>(time_enabled_sum) / time_running_sum; - scaled_count = static_cast<uint64_t>(scale * value_sum); - } + if (time_running_sum < time_enabled_sum && time_running_sum != 0) { + scale = static_cast<double>(time_enabled_sum) / time_running_sum; } CounterSummary summary; summary.event_type = counters_info.event_type; - summary.count = scaled_count; + summary.count = value_sum; summary.scale = scale; summary.readable_count_str = ReadableCountValue(summary.count, *summary.event_type); summaries.push_back(summary); |