aw: Move SharedRendererState out of AwContents
[chromium-blink-merge.git] / cc / resources / task_graph_runner_perftest.cc
blob7809e587975aebfb0abe213c573f1a420d1d8f49
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/task_graph_runner.h"
7 #include <vector>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/time/time.h"
11 #include "cc/base/completion_event.h"
12 #include "cc/debug/lap_timer.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/perf/perf_test.h"
16 namespace cc {
17 namespace {
19 static const int kTimeLimitMillis = 2000;
20 static const int kWarmupRuns = 5;
21 static const int kTimeCheckInterval = 10;
23 class PerfTaskImpl : public Task {
24 public:
25 typedef std::vector<scoped_refptr<PerfTaskImpl>> Vector;
27 PerfTaskImpl() {}
29 // Overridden from Task:
30 void RunOnWorkerThread() override {}
32 void Reset() { did_run_ = false; }
34 private:
35 ~PerfTaskImpl() override {}
37 DISALLOW_COPY_AND_ASSIGN(PerfTaskImpl);
40 class TaskGraphRunnerPerfTest : public testing::Test {
41 public:
42 TaskGraphRunnerPerfTest()
43 : timer_(kWarmupRuns,
44 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
45 kTimeCheckInterval) {}
47 // Overridden from testing::Test:
48 virtual void SetUp() override {
49 task_graph_runner_ = make_scoped_ptr(new TaskGraphRunner);
50 namespace_token_ = task_graph_runner_->GetNamespaceToken();
52 virtual void TearDown() override { task_graph_runner_ = nullptr; }
54 void AfterTest(const std::string& test_name) {
55 // Format matches chrome/test/perf/perf_test.h:PrintResult
56 printf(
57 "*RESULT %s: %.2f runs/s\n", test_name.c_str(), timer_.LapsPerSecond());
60 void RunBuildTaskGraphTest(const std::string& test_name,
61 int num_top_level_tasks,
62 int num_tasks,
63 int num_leaf_tasks) {
64 PerfTaskImpl::Vector top_level_tasks;
65 PerfTaskImpl::Vector tasks;
66 PerfTaskImpl::Vector leaf_tasks;
67 CreateTasks(num_top_level_tasks, &top_level_tasks);
68 CreateTasks(num_tasks, &tasks);
69 CreateTasks(num_leaf_tasks, &leaf_tasks);
71 // Avoid unnecessary heap allocations by reusing the same graph.
72 TaskGraph graph;
74 timer_.Reset();
75 do {
76 graph.Reset();
77 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph);
78 timer_.NextLap();
79 } while (!timer_.HasTimeLimitExpired());
81 perf_test::PrintResult("build_task_graph",
82 TestModifierString(),
83 test_name,
84 timer_.LapsPerSecond(),
85 "runs/s",
86 true);
89 void RunScheduleTasksTest(const std::string& test_name,
90 int num_top_level_tasks,
91 int num_tasks,
92 int num_leaf_tasks) {
93 PerfTaskImpl::Vector top_level_tasks;
94 PerfTaskImpl::Vector tasks;
95 PerfTaskImpl::Vector leaf_tasks;
96 CreateTasks(num_top_level_tasks, &top_level_tasks);
97 CreateTasks(num_tasks, &tasks);
98 CreateTasks(num_leaf_tasks, &leaf_tasks);
100 // Avoid unnecessary heap allocations by reusing the same graph and
101 // completed tasks vector.
102 TaskGraph graph;
103 Task::Vector completed_tasks;
105 timer_.Reset();
106 do {
107 graph.Reset();
108 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph);
109 task_graph_runner_->ScheduleTasks(namespace_token_, &graph);
110 // Shouldn't be any tasks to collect as we reschedule the same set
111 // of tasks.
112 DCHECK_EQ(0u, CollectCompletedTasks(&completed_tasks));
113 timer_.NextLap();
114 } while (!timer_.HasTimeLimitExpired());
116 TaskGraph empty;
117 task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
118 CollectCompletedTasks(&completed_tasks);
120 perf_test::PrintResult("schedule_tasks",
121 TestModifierString(),
122 test_name,
123 timer_.LapsPerSecond(),
124 "runs/s",
125 true);
128 void RunScheduleAlternateTasksTest(const std::string& test_name,
129 int num_top_level_tasks,
130 int num_tasks,
131 int num_leaf_tasks) {
132 const size_t kNumVersions = 2;
133 PerfTaskImpl::Vector top_level_tasks[kNumVersions];
134 PerfTaskImpl::Vector tasks[kNumVersions];
135 PerfTaskImpl::Vector leaf_tasks[kNumVersions];
136 for (size_t i = 0; i < kNumVersions; ++i) {
137 CreateTasks(num_top_level_tasks, &top_level_tasks[i]);
138 CreateTasks(num_tasks, &tasks[i]);
139 CreateTasks(num_leaf_tasks, &leaf_tasks[i]);
142 // Avoid unnecessary heap allocations by reusing the same graph and
143 // completed tasks vector.
144 TaskGraph graph;
145 Task::Vector completed_tasks;
147 size_t count = 0;
148 timer_.Reset();
149 do {
150 graph.Reset();
151 BuildTaskGraph(top_level_tasks[count % kNumVersions],
152 tasks[count % kNumVersions],
153 leaf_tasks[count % kNumVersions],
154 &graph);
155 task_graph_runner_->ScheduleTasks(namespace_token_, &graph);
156 CollectCompletedTasks(&completed_tasks);
157 completed_tasks.clear();
158 ++count;
159 timer_.NextLap();
160 } while (!timer_.HasTimeLimitExpired());
162 TaskGraph empty;
163 task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
164 CollectCompletedTasks(&completed_tasks);
166 perf_test::PrintResult("schedule_alternate_tasks",
167 TestModifierString(),
168 test_name,
169 timer_.LapsPerSecond(),
170 "runs/s",
171 true);
174 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
175 int num_top_level_tasks,
176 int num_tasks,
177 int num_leaf_tasks) {
178 PerfTaskImpl::Vector top_level_tasks;
179 PerfTaskImpl::Vector tasks;
180 PerfTaskImpl::Vector leaf_tasks;
181 CreateTasks(num_top_level_tasks, &top_level_tasks);
182 CreateTasks(num_tasks, &tasks);
183 CreateTasks(num_leaf_tasks, &leaf_tasks);
185 // Avoid unnecessary heap allocations by reusing the same graph and
186 // completed tasks vector.
187 TaskGraph graph;
188 Task::Vector completed_tasks;
190 timer_.Reset();
191 do {
192 graph.Reset();
193 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph);
194 task_graph_runner_->ScheduleTasks(namespace_token_, &graph);
195 task_graph_runner_->RunUntilIdle();
196 CollectCompletedTasks(&completed_tasks);
197 completed_tasks.clear();
198 ResetTasks(&top_level_tasks);
199 ResetTasks(&tasks);
200 ResetTasks(&leaf_tasks);
201 timer_.NextLap();
202 } while (!timer_.HasTimeLimitExpired());
204 perf_test::PrintResult("execute_tasks",
205 TestModifierString(),
206 test_name,
207 timer_.LapsPerSecond(),
208 "runs/s",
209 true);
212 private:
213 static std::string TestModifierString() {
214 return std::string("_task_graph_runner");
217 void CreateTasks(int num_tasks, PerfTaskImpl::Vector* tasks) {
218 for (int i = 0; i < num_tasks; ++i)
219 tasks->push_back(make_scoped_refptr(new PerfTaskImpl));
222 void ResetTasks(PerfTaskImpl::Vector* tasks) {
223 for (PerfTaskImpl::Vector::iterator it = tasks->begin(); it != tasks->end();
224 ++it) {
225 PerfTaskImpl* task = it->get();
226 task->Reset();
230 void BuildTaskGraph(const PerfTaskImpl::Vector& top_level_tasks,
231 const PerfTaskImpl::Vector& tasks,
232 const PerfTaskImpl::Vector& leaf_tasks,
233 TaskGraph* graph) {
234 DCHECK(graph->nodes.empty());
235 DCHECK(graph->edges.empty());
237 for (PerfTaskImpl::Vector::const_iterator it = leaf_tasks.begin();
238 it != leaf_tasks.end();
239 ++it) {
240 graph->nodes.push_back(TaskGraph::Node(it->get(), 0u, 0u));
243 for (PerfTaskImpl::Vector::const_iterator it = tasks.begin();
244 it != tasks.end();
245 ++it) {
246 graph->nodes.push_back(TaskGraph::Node(it->get(), 0u, leaf_tasks.size()));
248 for (PerfTaskImpl::Vector::const_iterator leaf_it = leaf_tasks.begin();
249 leaf_it != leaf_tasks.end();
250 ++leaf_it) {
251 graph->edges.push_back(TaskGraph::Edge(leaf_it->get(), it->get()));
254 for (PerfTaskImpl::Vector::const_iterator top_level_it =
255 top_level_tasks.begin();
256 top_level_it != top_level_tasks.end();
257 ++top_level_it) {
258 graph->edges.push_back(TaskGraph::Edge(it->get(), top_level_it->get()));
262 for (PerfTaskImpl::Vector::const_iterator it = top_level_tasks.begin();
263 it != top_level_tasks.end();
264 ++it) {
265 graph->nodes.push_back(TaskGraph::Node(it->get(), 0u, tasks.size()));
269 size_t CollectCompletedTasks(Task::Vector* completed_tasks) {
270 DCHECK(completed_tasks->empty());
271 task_graph_runner_->CollectCompletedTasks(namespace_token_,
272 completed_tasks);
273 return completed_tasks->size();
276 scoped_ptr<TaskGraphRunner> task_graph_runner_;
277 NamespaceToken namespace_token_;
278 LapTimer timer_;
281 TEST_F(TaskGraphRunnerPerfTest, BuildTaskGraph) {
282 RunBuildTaskGraphTest("0_1_0", 0, 1, 0);
283 RunBuildTaskGraphTest("0_32_0", 0, 32, 0);
284 RunBuildTaskGraphTest("2_1_0", 2, 1, 0);
285 RunBuildTaskGraphTest("2_32_0", 2, 32, 0);
286 RunBuildTaskGraphTest("2_1_1", 2, 1, 1);
287 RunBuildTaskGraphTest("2_32_1", 2, 32, 1);
290 TEST_F(TaskGraphRunnerPerfTest, ScheduleTasks) {
291 RunScheduleTasksTest("0_1_0", 0, 1, 0);
292 RunScheduleTasksTest("0_32_0", 0, 32, 0);
293 RunScheduleTasksTest("2_1_0", 2, 1, 0);
294 RunScheduleTasksTest("2_32_0", 2, 32, 0);
295 RunScheduleTasksTest("2_1_1", 2, 1, 1);
296 RunScheduleTasksTest("2_32_1", 2, 32, 1);
299 TEST_F(TaskGraphRunnerPerfTest, ScheduleAlternateTasks) {
300 RunScheduleAlternateTasksTest("0_1_0", 0, 1, 0);
301 RunScheduleAlternateTasksTest("0_32_0", 0, 32, 0);
302 RunScheduleAlternateTasksTest("2_1_0", 2, 1, 0);
303 RunScheduleAlternateTasksTest("2_32_0", 2, 32, 0);
304 RunScheduleAlternateTasksTest("2_1_1", 2, 1, 1);
305 RunScheduleAlternateTasksTest("2_32_1", 2, 32, 1);
308 TEST_F(TaskGraphRunnerPerfTest, ScheduleAndExecuteTasks) {
309 RunScheduleAndExecuteTasksTest("0_1_0", 0, 1, 0);
310 RunScheduleAndExecuteTasksTest("0_32_0", 0, 32, 0);
311 RunScheduleAndExecuteTasksTest("2_1_0", 2, 1, 0);
312 RunScheduleAndExecuteTasksTest("2_32_0", 2, 32, 0);
313 RunScheduleAndExecuteTasksTest("2_1_1", 2, 1, 1);
314 RunScheduleAndExecuteTasksTest("2_32_1", 2, 32, 1);
317 } // namespace
318 } // namespace cc