Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: cc/resources/worker_pool_perftest.cc

Issue 17244003: cc: Move task graph construction to RasterWorkerPool classes. (Closed) Base URL: http://git.chromium.org/chromium/src.git@wp-run-count
Patch Set: add missing CC_EXPORT Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/resources/worker_pool.cc ('k') | cc/resources/worker_pool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/resources/worker_pool.h" 5 #include "cc/resources/worker_pool.h"
6 6
7 #include "base/time.h" 7 #include "base/time.h"
8 #include "cc/base/completion_event.h" 8 #include "cc/base/completion_event.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 10
11 namespace cc { 11 namespace cc {
12 12
13 namespace { 13 namespace {
14 14
15 static const int kTimeLimitMillis = 2000; 15 static const int kTimeLimitMillis = 2000;
16 static const int kWarmupRuns = 5; 16 static const int kWarmupRuns = 5;
17 static const int kTimeCheckInterval = 10; 17 static const int kTimeCheckInterval = 10;
18 18
19 class PerfTaskImpl : public internal::WorkerPoolTask { 19 class PerfWorkerPoolTaskImpl : public internal::WorkerPoolTask {
20 public: 20 public:
21 explicit PerfTaskImpl(internal::WorkerPoolTask::TaskVector* dependencies)
22 : internal::WorkerPoolTask(dependencies) {}
23
24 // Overridden from internal::WorkerPoolTask: 21 // Overridden from internal::WorkerPoolTask:
25 virtual void RunOnThread(unsigned thread_index) OVERRIDE {} 22 virtual void RunOnThread(unsigned thread_index) OVERRIDE {}
26 virtual void DispatchCompletionCallback() OVERRIDE {} 23 virtual void DispatchCompletionCallback() OVERRIDE {}
27 24
28 private: 25 private:
29 virtual ~PerfTaskImpl() {} 26 virtual ~PerfWorkerPoolTaskImpl() {}
30 }; 27 };
31 28
32 class PerfControlTaskImpl : public internal::WorkerPoolTask { 29 class PerfControlWorkerPoolTaskImpl : public internal::WorkerPoolTask {
33 public: 30 public:
34 explicit PerfControlTaskImpl( 31 PerfControlWorkerPoolTaskImpl() : did_start_(new CompletionEvent),
35 internal::WorkerPoolTask::TaskVector* dependencies) 32 can_finish_(new CompletionEvent) {}
36 : internal::WorkerPoolTask(dependencies),
37 did_start_(new CompletionEvent),
38 can_finish_(new CompletionEvent) {}
39 33
40 // Overridden from internal::WorkerPoolTask: 34 // Overridden from internal::WorkerPoolTask:
41 virtual void RunOnThread(unsigned thread_index) OVERRIDE { 35 virtual void RunOnThread(unsigned thread_index) OVERRIDE {
42 did_start_->Signal(); 36 did_start_->Signal();
43 can_finish_->Wait(); 37 can_finish_->Wait();
44 } 38 }
45 virtual void DispatchCompletionCallback() OVERRIDE {} 39 virtual void DispatchCompletionCallback() OVERRIDE {}
46 40
47 void WaitForTaskToStartRunning() { 41 void WaitForTaskToStartRunning() {
48 did_start_->Wait(); 42 did_start_->Wait();
49 } 43 }
50 44
51 void AllowTaskToFinish() { 45 void AllowTaskToFinish() {
52 can_finish_->Signal(); 46 can_finish_->Signal();
53 } 47 }
54 48
55 private: 49 private:
56 virtual ~PerfControlTaskImpl() {} 50 virtual ~PerfControlWorkerPoolTaskImpl() {}
57 51
58 scoped_ptr<CompletionEvent> did_start_; 52 scoped_ptr<CompletionEvent> did_start_;
59 scoped_ptr<CompletionEvent> can_finish_; 53 scoped_ptr<CompletionEvent> can_finish_;
54
55 DISALLOW_COPY_AND_ASSIGN(PerfControlWorkerPoolTaskImpl);
60 }; 56 };
61 57
62 class PerfWorkerPool : public WorkerPool { 58 class PerfWorkerPool : public WorkerPool {
63 public: 59 public:
64 PerfWorkerPool() : WorkerPool(1, "test") {} 60 PerfWorkerPool() : WorkerPool(1, "test") {}
65 virtual ~PerfWorkerPool() {} 61 virtual ~PerfWorkerPool() {}
66 62
67 static scoped_ptr<PerfWorkerPool> Create() { 63 static scoped_ptr<PerfWorkerPool> Create() {
68 return make_scoped_ptr(new PerfWorkerPool); 64 return make_scoped_ptr(new PerfWorkerPool);
69 } 65 }
70 66
71 void BuildTaskGraph(internal::WorkerPoolTask* root) { 67 void ScheduleTasks(internal::WorkerPoolTask* root_task,
72 graph_.clear(); 68 internal::WorkerPoolTask* leaf_task,
73 WorkerPool::BuildTaskGraph(root, &graph_); 69 unsigned max_depth,
74 } 70 unsigned num_children_per_node) {
71 TaskVector tasks;
72 unsigned priority = 0u;
73 TaskGraph graph;
75 74
76 void ScheduleTasks() { 75 scoped_ptr<GraphNode> root_node;
77 SetTaskGraph(&graph_); 76 if (root_task) {
77 root_node = make_scoped_ptr(new GraphNode);
78 root_node->set_task(root_task);
79 }
80
81 scoped_ptr<GraphNode> leaf_node;
82 if (leaf_task) {
83 leaf_node = make_scoped_ptr(new GraphNode);
84 leaf_node->set_task(leaf_task);
85 }
86
87 if (max_depth) {
88 priority = BuildTaskGraph(&tasks,
89 &graph,
90 root_node.get(),
91 leaf_node.get(),
92 priority,
93 0,
94 max_depth,
95 num_children_per_node);
96 }
97
98 if (leaf_node) {
99 leaf_node->set_priority(priority++);
100 graph.set(leaf_task, leaf_node.Pass());
101 }
102
103 if (root_node) {
104 root_node->set_priority(priority++);
105 graph.set(root_task, root_node.Pass());
106 }
107
108 SetTaskGraph(&graph);
109
110 tasks_.swap(tasks);
78 } 111 }
79 112
80 private: 113 private:
81 TaskGraph graph_; 114 typedef std::vector<scoped_refptr<internal::WorkerPoolTask> > TaskVector;
115
116 unsigned BuildTaskGraph(TaskVector* tasks,
117 TaskGraph* graph,
118 GraphNode* dependent_node,
119 GraphNode* leaf_node,
120 unsigned priority,
121 unsigned current_depth,
122 unsigned max_depth,
123 unsigned num_children_per_node) {
124 scoped_refptr<PerfWorkerPoolTaskImpl> task(new PerfWorkerPoolTaskImpl);
125 scoped_ptr<GraphNode> node(new GraphNode);
126 node->set_task(task.get());
127
128 if (current_depth < max_depth) {
129 for (unsigned i = 0; i < num_children_per_node; ++i) {
130 priority = BuildTaskGraph(tasks,
131 graph,
132 node.get(),
133 leaf_node,
134 priority,
135 current_depth + 1,
136 max_depth,
137 num_children_per_node);
138 }
139 } else if (leaf_node) {
140 leaf_node->add_dependent(node.get());
141 node->add_dependency();
142 }
143
144 if (dependent_node) {
145 node->add_dependent(dependent_node);
146 dependent_node->add_dependency();
147 }
148 node->set_priority(priority);
149 graph->set(task.get(), node.Pass());
150 tasks->push_back(task.get());
151
152 return priority + 1;
153 }
154
155 TaskVector tasks_;
156
157 DISALLOW_COPY_AND_ASSIGN(PerfWorkerPool);
82 }; 158 };
83 159
84 class WorkerPoolPerfTest : public testing::Test { 160 class WorkerPoolPerfTest : public testing::Test {
85 public: 161 public:
86 WorkerPoolPerfTest() : num_runs_(0) {} 162 WorkerPoolPerfTest() : num_runs_(0) {}
87 163
88 // Overridden from testing::Test: 164 // Overridden from testing::Test:
89 virtual void SetUp() OVERRIDE { 165 virtual void SetUp() OVERRIDE {
90 worker_pool_ = PerfWorkerPool::Create(); 166 worker_pool_ = PerfWorkerPool::Create();
91 } 167 }
92 virtual void TearDown() OVERRIDE { 168 virtual void TearDown() OVERRIDE {
93 worker_pool_->Shutdown(); 169 worker_pool_->Shutdown();
94 worker_pool_->CheckForCompletedTasks(); 170 worker_pool_->CheckForCompletedTasks();
95 } 171 }
96 172
97 void EndTest() { 173 void EndTest() {
98 elapsed_ = base::TimeTicks::HighResNow() - start_time_; 174 elapsed_ = base::TimeTicks::HighResNow() - start_time_;
99 } 175 }
100 176
101 void AfterTest(const std::string test_name) { 177 void AfterTest(const std::string test_name) {
102 // Format matches chrome/test/perf/perf_test.h:PrintResult 178 // Format matches chrome/test/perf/perf_test.h:PrintResult
103 printf("*RESULT %s: %.2f runs/s\n", 179 printf("*RESULT %s: %.2f runs/s\n",
104 test_name.c_str(), 180 test_name.c_str(),
105 num_runs_ / elapsed_.InSecondsF()); 181 num_runs_ / elapsed_.InSecondsF());
106 } 182 }
107 183
108 void CreateTasks(internal::WorkerPoolTask::TaskVector* dependencies,
109 unsigned current_depth,
110 unsigned max_depth,
111 unsigned num_children_per_node) {
112 internal::WorkerPoolTask::TaskVector children;
113 if (current_depth < max_depth) {
114 for (unsigned i = 0; i < num_children_per_node; ++i) {
115 CreateTasks(&children,
116 current_depth + 1,
117 max_depth,
118 num_children_per_node);
119 }
120 } else if (leaf_task_.get()) {
121 children.push_back(leaf_task_);
122 }
123 dependencies->push_back(make_scoped_refptr(new PerfTaskImpl(&children)));
124 }
125
126 bool DidRun() { 184 bool DidRun() {
127 ++num_runs_; 185 ++num_runs_;
128 if (num_runs_ == kWarmupRuns) 186 if (num_runs_ == kWarmupRuns)
129 start_time_ = base::TimeTicks::HighResNow(); 187 start_time_ = base::TimeTicks::HighResNow();
130 188
131 if (!start_time_.is_null() && (num_runs_ % kTimeCheckInterval) == 0) { 189 if (!start_time_.is_null() && (num_runs_ % kTimeCheckInterval) == 0) {
132 base::TimeDelta elapsed = base::TimeTicks::HighResNow() - start_time_; 190 base::TimeDelta elapsed = base::TimeTicks::HighResNow() - start_time_;
133 if (elapsed >= base::TimeDelta::FromMilliseconds(kTimeLimitMillis)) { 191 if (elapsed >= base::TimeDelta::FromMilliseconds(kTimeLimitMillis)) {
134 elapsed_ = elapsed; 192 elapsed_ = elapsed;
135 return false; 193 return false;
136 } 194 }
137 } 195 }
138 196
139 return true; 197 return true;
140 } 198 }
141 199
142 void RunBuildTaskGraphTest(const std::string test_name,
143 unsigned max_depth,
144 unsigned num_children_per_node) {
145 start_time_ = base::TimeTicks();
146 num_runs_ = 0;
147 internal::WorkerPoolTask::TaskVector children;
148 CreateTasks(&children, 0, max_depth, num_children_per_node);
149 scoped_refptr<PerfTaskImpl> root_task(
150 make_scoped_refptr(new PerfTaskImpl(&children)));
151 do {
152 worker_pool_->BuildTaskGraph(root_task.get());
153 } while (DidRun());
154
155 AfterTest(test_name);
156 }
157
158 void RunScheduleTasksTest(const std::string test_name, 200 void RunScheduleTasksTest(const std::string test_name,
159 unsigned max_depth, 201 unsigned max_depth,
160 unsigned num_children_per_node) { 202 unsigned num_children_per_node) {
161 start_time_ = base::TimeTicks(); 203 start_time_ = base::TimeTicks();
162 num_runs_ = 0; 204 num_runs_ = 0;
163 do { 205 do {
164 internal::WorkerPoolTask::TaskVector empty; 206 scoped_refptr<PerfControlWorkerPoolTaskImpl> leaf_task(
165 leaf_task_ = make_scoped_refptr(new PerfControlTaskImpl(&empty)); 207 new PerfControlWorkerPoolTaskImpl);
166 internal::WorkerPoolTask::TaskVector children; 208 worker_pool_->ScheduleTasks(
167 CreateTasks(&children, 0, max_depth, num_children_per_node); 209 NULL, leaf_task.get(), max_depth, num_children_per_node);
168 scoped_refptr<PerfTaskImpl> root_task( 210 leaf_task->WaitForTaskToStartRunning();
169 make_scoped_refptr(new PerfTaskImpl(&children))); 211 worker_pool_->ScheduleTasks(NULL, NULL, 0, 0);
170
171 worker_pool_->BuildTaskGraph(root_task.get());
172 worker_pool_->ScheduleTasks();
173 leaf_task_->WaitForTaskToStartRunning();
174 worker_pool_->BuildTaskGraph(NULL);
175 worker_pool_->ScheduleTasks();
176 worker_pool_->CheckForCompletedTasks(); 212 worker_pool_->CheckForCompletedTasks();
177 leaf_task_->AllowTaskToFinish(); 213 leaf_task->AllowTaskToFinish();
178 } while (DidRun()); 214 } while (DidRun());
179 215
180 AfterTest(test_name); 216 AfterTest(test_name);
181 } 217 }
182 218
183 void RunExecuteTasksTest(const std::string test_name, 219 void RunExecuteTasksTest(const std::string test_name,
184 unsigned max_depth, 220 unsigned max_depth,
185 unsigned num_children_per_node) { 221 unsigned num_children_per_node) {
186 start_time_ = base::TimeTicks(); 222 start_time_ = base::TimeTicks();
187 num_runs_ = 0; 223 num_runs_ = 0;
188 do { 224 do {
189 internal::WorkerPoolTask::TaskVector children; 225 scoped_refptr<PerfControlWorkerPoolTaskImpl> root_task(
190 CreateTasks(&children, 0, max_depth, num_children_per_node); 226 new PerfControlWorkerPoolTaskImpl);
191 scoped_refptr<PerfControlTaskImpl> root_task( 227 worker_pool_->ScheduleTasks(
192 make_scoped_refptr(new PerfControlTaskImpl(&children))); 228 root_task.get(), NULL, max_depth, num_children_per_node);
193
194 worker_pool_->BuildTaskGraph(root_task.get());
195 worker_pool_->ScheduleTasks();
196 root_task->WaitForTaskToStartRunning(); 229 root_task->WaitForTaskToStartRunning();
197 root_task->AllowTaskToFinish(); 230 root_task->AllowTaskToFinish();
198 worker_pool_->CheckForCompletedTasks(); 231 worker_pool_->CheckForCompletedTasks();
199 } while (DidRun()); 232 } while (DidRun());
200 233
201 AfterTest(test_name); 234 AfterTest(test_name);
202 } 235 }
203 236
204 protected: 237 protected:
205 scoped_ptr<PerfWorkerPool> worker_pool_; 238 scoped_ptr<PerfWorkerPool> worker_pool_;
206 scoped_refptr<PerfControlTaskImpl> leaf_task_;
207 base::TimeTicks start_time_; 239 base::TimeTicks start_time_;
208 base::TimeDelta elapsed_; 240 base::TimeDelta elapsed_;
209 int num_runs_; 241 int num_runs_;
210 }; 242 };
211 243
212 TEST_F(WorkerPoolPerfTest, BuildTaskGraph) {
213 RunBuildTaskGraphTest("build_task_graph_1_10", 1, 10);
214 RunBuildTaskGraphTest("build_task_graph_1_1000", 1, 1000);
215 RunBuildTaskGraphTest("build_task_graph_2_10", 2, 10);
216 RunBuildTaskGraphTest("build_task_graph_5_5", 5, 5);
217 RunBuildTaskGraphTest("build_task_graph_10_2", 10, 2);
218 RunBuildTaskGraphTest("build_task_graph_1000_1", 1000, 1);
219 RunBuildTaskGraphTest("build_task_graph_10_1", 10, 1);
220 }
221
222 TEST_F(WorkerPoolPerfTest, ScheduleTasks) { 244 TEST_F(WorkerPoolPerfTest, ScheduleTasks) {
223 RunScheduleTasksTest("schedule_tasks_1_10", 1, 10); 245 RunScheduleTasksTest("schedule_tasks_1_10", 1, 10);
224 RunScheduleTasksTest("schedule_tasks_1_1000", 1, 1000); 246 RunScheduleTasksTest("schedule_tasks_1_1000", 1, 1000);
225 RunScheduleTasksTest("schedule_tasks_2_10", 2, 10); 247 RunScheduleTasksTest("schedule_tasks_2_10", 2, 10);
226 RunScheduleTasksTest("schedule_tasks_5_5", 5, 5); 248 RunScheduleTasksTest("schedule_tasks_5_5", 5, 5);
227 RunScheduleTasksTest("schedule_tasks_10_2", 10, 2); 249 RunScheduleTasksTest("schedule_tasks_10_2", 10, 2);
228 RunScheduleTasksTest("schedule_tasks_1000_1", 1000, 1); 250 RunScheduleTasksTest("schedule_tasks_1000_1", 1000, 1);
229 RunScheduleTasksTest("schedule_tasks_10_1", 10, 1); 251 RunScheduleTasksTest("schedule_tasks_10_1", 10, 1);
230 } 252 }
231 253
232 TEST_F(WorkerPoolPerfTest, ExecuteTasks) { 254 TEST_F(WorkerPoolPerfTest, ExecuteTasks) {
233 RunExecuteTasksTest("execute_tasks_1_10", 1, 10); 255 RunExecuteTasksTest("execute_tasks_1_10", 1, 10);
234 RunExecuteTasksTest("execute_tasks_1_1000", 1, 1000); 256 RunExecuteTasksTest("execute_tasks_1_1000", 1, 1000);
235 RunExecuteTasksTest("execute_tasks_2_10", 2, 10); 257 RunExecuteTasksTest("execute_tasks_2_10", 2, 10);
236 RunExecuteTasksTest("execute_tasks_5_5", 5, 5); 258 RunExecuteTasksTest("execute_tasks_5_5", 5, 5);
237 RunExecuteTasksTest("execute_tasks_10_2", 10, 2); 259 RunExecuteTasksTest("execute_tasks_10_2", 10, 2);
238 RunExecuteTasksTest("execute_tasks_1000_1", 1000, 1); 260 RunExecuteTasksTest("execute_tasks_1000_1", 1000, 1);
239 RunExecuteTasksTest("execute_tasks_10_1", 10, 1); 261 RunExecuteTasksTest("execute_tasks_10_1", 10, 1);
240 } 262 }
241 263
242 } // namespace 264 } // namespace
243 265
244 } // namespace cc 266 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/worker_pool.cc ('k') | cc/resources/worker_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698