summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-03-06 22:03:32 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-03-06 22:03:32 +0000
commit0b922984847bda4c0e00f07dc404664909a1fcc0 (patch)
treee8dbf7301ce48eb51299fbe8c17555e29d98620d
parent8e57dc74b071793296389d0d936f385d0949df76 (diff)
parent900ea0706e16bd2afc99f95a56b67b364800ad60 (diff)
downloadextras-0b922984847bda4c0e00f07dc404664909a1fcc0.tar.gz
Merge "simpleperf: fix calculating cpu frequency."
-rw-r--r--simpleperf/cmd_debug_unwind_test.cpp42
-rw-r--r--simpleperf/cmd_stat.cpp23
-rw-r--r--simpleperf/cmd_stat_test.cpp25
-rw-r--r--simpleperf/test_util.h45
4 files changed, 91 insertions, 44 deletions
diff --git a/simpleperf/cmd_debug_unwind_test.cpp b/simpleperf/cmd_debug_unwind_test.cpp
index 153adb75..7b99afaa 100644
--- a/simpleperf/cmd_debug_unwind_test.cpp
+++ b/simpleperf/cmd_debug_unwind_test.cpp
@@ -34,48 +34,6 @@ static std::unique_ptr<Command> DebugUnwindCmd() {
return CreateCommandInstance("debug-unwind");
}
-class CaptureStdout {
- public:
- CaptureStdout() : started_(false) {}
-
- ~CaptureStdout() {
- if (started_) {
- Finish();
- }
- }
-
- bool Start() {
- fflush(stdout);
- old_stdout_ = dup(STDOUT_FILENO);
- if (old_stdout_ == -1) {
- return false;
- }
- started_ = true;
- tmpfile_.reset(new TemporaryFile);
- if (dup2(tmpfile_->fd, STDOUT_FILENO) == -1) {
- return false;
- }
- return true;
- }
-
- std::string Finish() {
- fflush(stdout);
- started_ = false;
- dup2(old_stdout_, STDOUT_FILENO);
- close(old_stdout_);
- std::string s;
- if (!android::base::ReadFileToString(tmpfile_->path, &s)) {
- return "";
- }
- return s;
- }
-
- private:
- bool started_;
- int old_stdout_;
- std::unique_ptr<TemporaryFile> tmpfile_;
-};
-
TEST(cmd_debug_unwind, smoke) {
std::string input_data = GetTestData(PERF_DATA_NO_UNWIND);
CaptureStdout capture;
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 34b4436c..6872a89c 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -210,7 +210,11 @@ class CounterSummaries {
return "";
}
if (s.type_name == "cpu-cycles") {
- double hz = s.count / (duration_in_sec / s.scale);
+ double running_time_in_sec;
+ if (!FindRunningTimeForSummary(s, &running_time_in_sec)) {
+ return "";
+ }
+ double hz = s.count / (running_time_in_sec / s.scale);
return android::base::StringPrintf("%lf%cGHz", hz / 1e9, sap_mid);
}
if (s.type_name == "instructions" && s.count != 0) {
@@ -247,7 +251,11 @@ class CounterSummaries {
return android::base::StringPrintf("%f%%%cmiss rate", miss_rate * 100, sap_mid);
}
}
- double rate = s.count / (duration_in_sec / s.scale);
+ double running_time_in_sec;
+ if (!FindRunningTimeForSummary(s, &running_time_in_sec)) {
+ return "";
+ }
+ double rate = s.count / (running_time_in_sec / s.scale);
if (rate > 1e9) {
return android::base::StringPrintf("%.3lf%cG/sec", rate / 1e9, sap_mid);
}
@@ -260,6 +268,17 @@ class CounterSummaries {
return android::base::StringPrintf("%.3lf%c/sec", rate, sap_mid);
}
+ bool FindRunningTimeForSummary(const CounterSummary& summary, double* running_time_in_sec) {
+ for (auto& s : summaries_) {
+ if ((s.type_name == "task-clock" || s.type_name == "cpu-clock") &&
+ s.IsMonitoredAtTheSameTime(summary) && s.count != 0u) {
+ *running_time_in_sec = s.count / 1e9;
+ return true;
+ }
+ }
+ return false;
+ }
+
private:
std::vector<CounterSummary> summaries_;
bool csv_;
diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp
index b6896e14..ae3b0360 100644
--- a/simpleperf/cmd_stat_test.cpp
+++ b/simpleperf/cmd_stat_test.cpp
@@ -18,6 +18,7 @@
#include <android-base/file.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <thread>
@@ -194,3 +195,27 @@ TEST(stat_cmd, sample_speed_should_be_zero) {
ASSERT_EQ(attr.attr->freq, 0u);
}
}
+
+TEST(stat_cmd, calculating_cpu_frequency) {
+ CaptureStdout capture;
+ ASSERT_TRUE(capture.Start());
+ ASSERT_TRUE(StatCmd()->Run({"--csv", "--group", "task-clock,cpu-cycles", "sleep", "1"}));
+ std::string output = capture.Finish();
+ double task_clock_in_ms = 0;
+ uint64_t cpu_cycle_count = 0;
+ double cpu_frequency = 0;
+ for (auto& line : android::base::Split(output, "\n")) {
+ if (line.find("task-clock") != std::string::npos) {
+ ASSERT_EQ(sscanf(line.c_str(), "%lf(ms)", &task_clock_in_ms), 1);
+ } else if (line.find("cpu-cycles") != std::string::npos) {
+ ASSERT_EQ(sscanf(line.c_str(), "%" SCNu64 ",cpu-cycles,%lf", &cpu_cycle_count,
+ &cpu_frequency), 2);
+ }
+ }
+ ASSERT_NE(task_clock_in_ms, 0.0f);
+ ASSERT_NE(cpu_cycle_count, 0u);
+ ASSERT_NE(cpu_frequency, 0.0f);
+ double calculated_frequency = cpu_cycle_count / task_clock_in_ms / 1e6;
+ // Accept error up to 1e-3. Because the stat cmd print values with precision 1e-6.
+ ASSERT_NEAR(cpu_frequency, calculated_frequency, 1e-3);
+}
diff --git a/simpleperf/test_util.h b/simpleperf/test_util.h
index f5fb590f..8768d666 100644
--- a/simpleperf/test_util.h
+++ b/simpleperf/test_util.h
@@ -19,6 +19,9 @@
#include <string>
#include <vector>
+#include <android-base/file.h>
+#include <android-base/test_utils.h>
+
#include "read_elf.h"
#include "workload.h"
@@ -56,3 +59,45 @@ bool IsInNativeAbi();
return; \
} \
} while (0)
+
+class CaptureStdout {
+ public:
+ CaptureStdout() : started_(false) {}
+
+ ~CaptureStdout() {
+ if (started_) {
+ Finish();
+ }
+ }
+
+ bool Start() {
+ fflush(stdout);
+ old_stdout_ = dup(STDOUT_FILENO);
+ if (old_stdout_ == -1) {
+ return false;
+ }
+ started_ = true;
+ tmpfile_.reset(new TemporaryFile);
+ if (dup2(tmpfile_->fd, STDOUT_FILENO) == -1) {
+ return false;
+ }
+ return true;
+ }
+
+ std::string Finish() {
+ fflush(stdout);
+ started_ = false;
+ dup2(old_stdout_, STDOUT_FILENO);
+ close(old_stdout_);
+ std::string s;
+ if (!android::base::ReadFileToString(tmpfile_->path, &s)) {
+ return "";
+ }
+ return s;
+ }
+
+ private:
+ bool started_;
+ int old_stdout_;
+ std::unique_ptr<TemporaryFile> tmpfile_;
+};