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

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

Issue 154003006: cc: Switch to vector based TaskGraph implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: build fix Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « cc/resources/task_graph_runner.cc ('k') | cc/resources/task_graph_runner_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 2014 The Chromium Authors. All rights reserved. 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 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/task_graph_runner.h" 5 #include "cc/resources/task_graph_runner.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/time/time.h" 9 #include "base/time/time.h"
10 #include "cc/base/completion_event.h" 10 #include "cc/base/completion_event.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 int num_top_level_tasks, 62 int num_top_level_tasks,
63 int num_tasks, 63 int num_tasks,
64 int num_leaf_tasks) { 64 int num_leaf_tasks) {
65 PerfTaskImpl::Vector top_level_tasks; 65 PerfTaskImpl::Vector top_level_tasks;
66 PerfTaskImpl::Vector tasks; 66 PerfTaskImpl::Vector tasks;
67 PerfTaskImpl::Vector leaf_tasks; 67 PerfTaskImpl::Vector leaf_tasks;
68 CreateTasks(num_top_level_tasks, &top_level_tasks); 68 CreateTasks(num_top_level_tasks, &top_level_tasks);
69 CreateTasks(num_tasks, &tasks); 69 CreateTasks(num_tasks, &tasks);
70 CreateTasks(num_leaf_tasks, &leaf_tasks); 70 CreateTasks(num_leaf_tasks, &leaf_tasks);
71 71
72 // Avoid unnecessary heap allocations by reusing the same graph.
73 internal::TaskGraph graph;
74
72 timer_.Reset(); 75 timer_.Reset();
73 do { 76 do {
74 internal::GraphNode::Map graph; 77 graph.Reset();
75 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph); 78 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph);
76 timer_.NextLap(); 79 timer_.NextLap();
77 } while (!timer_.HasTimeLimitExpired()); 80 } while (!timer_.HasTimeLimitExpired());
78 81
79 perf_test::PrintResult("build_task_graph", 82 perf_test::PrintResult("build_task_graph",
80 "", 83 "",
81 test_name, 84 test_name,
82 timer_.LapsPerSecond(), 85 timer_.LapsPerSecond(),
83 "runs/s", 86 "runs/s",
84 true); 87 true);
85 } 88 }
86 89
87 void RunScheduleTasksTest(const std::string& test_name, 90 void RunScheduleTasksTest(const std::string& test_name,
88 int num_top_level_tasks, 91 int num_top_level_tasks,
89 int num_tasks, 92 int num_tasks,
90 int num_leaf_tasks) { 93 int num_leaf_tasks) {
91 PerfTaskImpl::Vector top_level_tasks; 94 PerfTaskImpl::Vector top_level_tasks;
92 PerfTaskImpl::Vector tasks; 95 PerfTaskImpl::Vector tasks;
93 PerfTaskImpl::Vector leaf_tasks; 96 PerfTaskImpl::Vector leaf_tasks;
94 CreateTasks(num_top_level_tasks, &top_level_tasks); 97 CreateTasks(num_top_level_tasks, &top_level_tasks);
95 CreateTasks(num_tasks, &tasks); 98 CreateTasks(num_tasks, &tasks);
96 CreateTasks(num_leaf_tasks, &leaf_tasks); 99 CreateTasks(num_leaf_tasks, &leaf_tasks);
97 100
101 // Avoid unnecessary heap allocations by reusing the same graph and
102 // completed tasks vector.
103 internal::TaskGraph graph;
104 internal::Task::Vector completed_tasks;
105
98 timer_.Reset(); 106 timer_.Reset();
99 do { 107 do {
100 internal::GraphNode::Map graph; 108 graph.Reset();
101 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph); 109 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph);
102 task_graph_runner_->SetTaskGraph(namespace_token_, &graph); 110 task_graph_runner_->SetTaskGraph(namespace_token_, &graph);
103 // Shouldn't be any tasks to collect as we reschedule the same set 111 // Shouldn't be any tasks to collect as we reschedule the same set
104 // of tasks. 112 // of tasks.
105 DCHECK_EQ(0u, CollectCompletedTasks()); 113 DCHECK_EQ(0u, CollectCompletedTasks(&completed_tasks));
106 timer_.NextLap(); 114 timer_.NextLap();
107 } while (!timer_.HasTimeLimitExpired()); 115 } while (!timer_.HasTimeLimitExpired());
108 116
109 internal::GraphNode::Map empty; 117 internal::TaskGraph empty;
110 task_graph_runner_->SetTaskGraph(namespace_token_, &empty); 118 task_graph_runner_->SetTaskGraph(namespace_token_, &empty);
111 CollectCompletedTasks(); 119 CollectCompletedTasks(&completed_tasks);
112 120
113 perf_test::PrintResult("schedule_tasks", 121 perf_test::PrintResult("schedule_tasks",
114 "", 122 "",
115 test_name, 123 test_name,
116 timer_.LapsPerSecond(), 124 timer_.LapsPerSecond(),
117 "runs/s", 125 "runs/s",
118 true); 126 true);
119 } 127 }
120 128
121 void RunScheduleAlternateTasksTest(const std::string& test_name, 129 void RunScheduleAlternateTasksTest(const std::string& test_name,
122 int num_top_level_tasks, 130 int num_top_level_tasks,
123 int num_tasks, 131 int num_tasks,
124 int num_leaf_tasks) { 132 int num_leaf_tasks) {
125 const int kNumVersions = 2; 133 const int kNumVersions = 2;
126 PerfTaskImpl::Vector top_level_tasks[kNumVersions]; 134 PerfTaskImpl::Vector top_level_tasks[kNumVersions];
127 PerfTaskImpl::Vector tasks[kNumVersions]; 135 PerfTaskImpl::Vector tasks[kNumVersions];
128 PerfTaskImpl::Vector leaf_tasks[kNumVersions]; 136 PerfTaskImpl::Vector leaf_tasks[kNumVersions];
129 for (int i = 0; i < kNumVersions; ++i) { 137 for (int i = 0; i < kNumVersions; ++i) {
130 CreateTasks(num_top_level_tasks, &top_level_tasks[i]); 138 CreateTasks(num_top_level_tasks, &top_level_tasks[i]);
131 CreateTasks(num_tasks, &tasks[i]); 139 CreateTasks(num_tasks, &tasks[i]);
132 CreateTasks(num_leaf_tasks, &leaf_tasks[i]); 140 CreateTasks(num_leaf_tasks, &leaf_tasks[i]);
133 } 141 }
134 142
143 // Avoid unnecessary heap allocations by reusing the same graph and
144 // completed tasks vector.
145 internal::TaskGraph graph;
146 internal::Task::Vector completed_tasks;
147
135 int count = 0; 148 int count = 0;
136 timer_.Reset(); 149 timer_.Reset();
137 do { 150 do {
138 internal::GraphNode::Map graph; 151 graph.Reset();
139 BuildTaskGraph(top_level_tasks[count % kNumVersions], 152 BuildTaskGraph(top_level_tasks[count % kNumVersions],
140 tasks[count % kNumVersions], 153 tasks[count % kNumVersions],
141 leaf_tasks[count % kNumVersions], 154 leaf_tasks[count % kNumVersions],
142 &graph); 155 &graph);
143 task_graph_runner_->SetTaskGraph(namespace_token_, &graph); 156 task_graph_runner_->SetTaskGraph(namespace_token_, &graph);
144 CollectCompletedTasks(); 157 CollectCompletedTasks(&completed_tasks);
158 completed_tasks.clear();
145 ++count; 159 ++count;
146 timer_.NextLap(); 160 timer_.NextLap();
147 } while (!timer_.HasTimeLimitExpired()); 161 } while (!timer_.HasTimeLimitExpired());
148 162
149 internal::GraphNode::Map empty; 163 internal::TaskGraph empty;
150 task_graph_runner_->SetTaskGraph(namespace_token_, &empty); 164 task_graph_runner_->SetTaskGraph(namespace_token_, &empty);
151 CollectCompletedTasks(); 165 CollectCompletedTasks(&completed_tasks);
152 166
153 perf_test::PrintResult("schedule_alternate_tasks", 167 perf_test::PrintResult("schedule_alternate_tasks",
154 "", 168 "",
155 test_name, 169 test_name,
156 timer_.LapsPerSecond(), 170 timer_.LapsPerSecond(),
157 "runs/s", 171 "runs/s",
158 true); 172 true);
159 } 173 }
160 174
161 void RunScheduleAndExecuteTasksTest(const std::string& test_name, 175 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
162 int num_top_level_tasks, 176 int num_top_level_tasks,
163 int num_tasks, 177 int num_tasks,
164 int num_leaf_tasks) { 178 int num_leaf_tasks) {
165 PerfTaskImpl::Vector top_level_tasks; 179 PerfTaskImpl::Vector top_level_tasks;
166 PerfTaskImpl::Vector tasks; 180 PerfTaskImpl::Vector tasks;
167 PerfTaskImpl::Vector leaf_tasks; 181 PerfTaskImpl::Vector leaf_tasks;
168 CreateTasks(num_top_level_tasks, &top_level_tasks); 182 CreateTasks(num_top_level_tasks, &top_level_tasks);
169 CreateTasks(num_tasks, &tasks); 183 CreateTasks(num_tasks, &tasks);
170 CreateTasks(num_leaf_tasks, &leaf_tasks); 184 CreateTasks(num_leaf_tasks, &leaf_tasks);
171 185
186 // Avoid unnecessary heap allocations by reusing the same graph and
187 // completed tasks vector.
188 internal::TaskGraph graph;
189 internal::Task::Vector completed_tasks;
190
172 timer_.Reset(); 191 timer_.Reset();
173 do { 192 do {
174 internal::GraphNode::Map graph; 193 graph.Reset();
175 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph); 194 BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph);
176 task_graph_runner_->SetTaskGraph(namespace_token_, &graph); 195 task_graph_runner_->SetTaskGraph(namespace_token_, &graph);
177 while (task_graph_runner_->RunTaskForTesting()) 196 while (task_graph_runner_->RunTaskForTesting())
178 continue; 197 continue;
179 CollectCompletedTasks(); 198 CollectCompletedTasks(&completed_tasks);
199 completed_tasks.clear();
180 ResetTasks(&top_level_tasks); 200 ResetTasks(&top_level_tasks);
181 ResetTasks(&tasks); 201 ResetTasks(&tasks);
182 ResetTasks(&leaf_tasks); 202 ResetTasks(&leaf_tasks);
183 timer_.NextLap(); 203 timer_.NextLap();
184 } while (!timer_.HasTimeLimitExpired()); 204 } while (!timer_.HasTimeLimitExpired());
185 205
186 perf_test::PrintResult( 206 perf_test::PrintResult(
187 "execute_tasks", "", test_name, timer_.LapsPerSecond(), "runs/s", true); 207 "execute_tasks", "", test_name, timer_.LapsPerSecond(), "runs/s", true);
188 } 208 }
189 209
190 private: 210 private:
191 void CreateTasks(int num_tasks, PerfTaskImpl::Vector* tasks) { 211 void CreateTasks(int num_tasks, PerfTaskImpl::Vector* tasks) {
192 for (int i = 0; i < num_tasks; ++i) 212 for (int i = 0; i < num_tasks; ++i)
193 tasks->push_back(make_scoped_refptr(new PerfTaskImpl)); 213 tasks->push_back(make_scoped_refptr(new PerfTaskImpl));
194 } 214 }
195 215
196 void ResetTasks(PerfTaskImpl::Vector* tasks) { 216 void ResetTasks(PerfTaskImpl::Vector* tasks) {
197 for (PerfTaskImpl::Vector::iterator it = tasks->begin(); it != tasks->end(); 217 for (PerfTaskImpl::Vector::iterator it = tasks->begin(); it != tasks->end();
198 ++it) { 218 ++it) {
199 PerfTaskImpl* task = it->get(); 219 PerfTaskImpl* task = it->get();
200 task->Reset(); 220 task->Reset();
201 } 221 }
202 } 222 }
203 223
204 void BuildTaskGraph(const PerfTaskImpl::Vector& top_level_tasks, 224 void BuildTaskGraph(const PerfTaskImpl::Vector& top_level_tasks,
205 const PerfTaskImpl::Vector& tasks, 225 const PerfTaskImpl::Vector& tasks,
206 const PerfTaskImpl::Vector& leaf_tasks, 226 const PerfTaskImpl::Vector& leaf_tasks,
207 internal::GraphNode::Map* graph) { 227 internal::TaskGraph* graph) {
208 typedef std::vector<internal::GraphNode*> NodeVector; 228 DCHECK(graph->nodes.empty());
229 DCHECK(graph->edges.empty());
209 230
210 NodeVector top_level_nodes;
211 top_level_nodes.reserve(top_level_tasks.size());
212 for (PerfTaskImpl::Vector::const_iterator it = top_level_tasks.begin();
213 it != top_level_tasks.end();
214 ++it) {
215 internal::Task* top_level_task = it->get();
216 scoped_ptr<internal::GraphNode> top_level_node(
217 new internal::GraphNode(top_level_task, 0u));
218
219 top_level_nodes.push_back(top_level_node.get());
220 graph->set(top_level_task, top_level_node.Pass());
221 }
222
223 NodeVector leaf_nodes;
224 leaf_nodes.reserve(leaf_tasks.size());
225 for (PerfTaskImpl::Vector::const_iterator it = leaf_tasks.begin(); 231 for (PerfTaskImpl::Vector::const_iterator it = leaf_tasks.begin();
226 it != leaf_tasks.end(); 232 it != leaf_tasks.end();
227 ++it) { 233 ++it) {
228 internal::Task* leaf_task = it->get(); 234 graph->nodes.push_back(internal::TaskGraph::Node(it->get(), 0u, 0u));
229 scoped_ptr<internal::GraphNode> leaf_node(
230 new internal::GraphNode(leaf_task, 0u));
231
232 leaf_nodes.push_back(leaf_node.get());
233 graph->set(leaf_task, leaf_node.Pass());
234 } 235 }
235 236
236 for (PerfTaskImpl::Vector::const_iterator it = tasks.begin(); 237 for (PerfTaskImpl::Vector::const_iterator it = tasks.begin();
237 it != tasks.end(); 238 it != tasks.end();
238 ++it) { 239 ++it) {
239 internal::Task* task = it->get(); 240 graph->nodes.push_back(
240 scoped_ptr<internal::GraphNode> node(new internal::GraphNode(task, 0u)); 241 internal::TaskGraph::Node(it->get(), 0u, leaf_tasks.size()));
241 242
242 for (NodeVector::iterator node_it = top_level_nodes.begin(); 243 for (PerfTaskImpl::Vector::const_iterator leaf_it = leaf_tasks.begin();
243 node_it != top_level_nodes.end(); 244 leaf_it != leaf_tasks.end();
244 ++node_it) { 245 ++leaf_it) {
245 internal::GraphNode* top_level_node = *node_it; 246 graph->edges.push_back(
246 node->add_dependent(top_level_node); 247 internal::TaskGraph::Edge(leaf_it->get(), it->get()));
247 top_level_node->add_dependency();
248 } 248 }
249 249
250 for (NodeVector::iterator node_it = leaf_nodes.begin(); 250 for (PerfTaskImpl::Vector::const_iterator top_level_it =
251 node_it != leaf_nodes.end(); 251 top_level_tasks.begin();
252 ++node_it) { 252 top_level_it != top_level_tasks.end();
253 internal::GraphNode* leaf_node = *node_it; 253 ++top_level_it) {
254 leaf_node->add_dependent(node.get()); 254 graph->edges.push_back(
255 node->add_dependency(); 255 internal::TaskGraph::Edge(it->get(), top_level_it->get()));
256 } 256 }
257 }
257 258
258 graph->set(task, node.Pass()); 259 for (PerfTaskImpl::Vector::const_iterator it = top_level_tasks.begin();
260 it != top_level_tasks.end();
261 ++it) {
262 graph->nodes.push_back(
263 internal::TaskGraph::Node(it->get(), 0u, tasks.size()));
259 } 264 }
260 } 265 }
261 266
262 size_t CollectCompletedTasks() { 267 size_t CollectCompletedTasks(internal::Task::Vector* completed_tasks) {
263 internal::Task::Vector completed_tasks; 268 DCHECK(completed_tasks->empty());
264 task_graph_runner_->CollectCompletedTasks(namespace_token_, 269 task_graph_runner_->CollectCompletedTasks(namespace_token_,
265 &completed_tasks); 270 completed_tasks);
266 return completed_tasks.size(); 271 return completed_tasks->size();
267 } 272 }
268 273
269 scoped_ptr<internal::TaskGraphRunner> task_graph_runner_; 274 scoped_ptr<internal::TaskGraphRunner> task_graph_runner_;
270 internal::NamespaceToken namespace_token_; 275 internal::NamespaceToken namespace_token_;
271 LapTimer timer_; 276 LapTimer timer_;
272 }; 277 };
273 278
274 TEST_F(TaskGraphRunnerPerfTest, BuildTaskGraph) { 279 TEST_F(TaskGraphRunnerPerfTest, BuildTaskGraph) {
275 RunBuildTaskGraphTest("0_1_0", 0, 1, 0); 280 RunBuildTaskGraphTest("0_1_0", 0, 1, 0);
276 RunBuildTaskGraphTest("0_32_0", 0, 32, 0); 281 RunBuildTaskGraphTest("0_32_0", 0, 32, 0);
(...skipping 25 matching lines...) Expand all
302 RunScheduleAndExecuteTasksTest("0_1_0", 0, 1, 0); 307 RunScheduleAndExecuteTasksTest("0_1_0", 0, 1, 0);
303 RunScheduleAndExecuteTasksTest("0_32_0", 0, 32, 0); 308 RunScheduleAndExecuteTasksTest("0_32_0", 0, 32, 0);
304 RunScheduleAndExecuteTasksTest("2_1_0", 2, 1, 0); 309 RunScheduleAndExecuteTasksTest("2_1_0", 2, 1, 0);
305 RunScheduleAndExecuteTasksTest("2_32_0", 2, 32, 0); 310 RunScheduleAndExecuteTasksTest("2_32_0", 2, 32, 0);
306 RunScheduleAndExecuteTasksTest("2_1_1", 2, 1, 1); 311 RunScheduleAndExecuteTasksTest("2_1_1", 2, 1, 1);
307 RunScheduleAndExecuteTasksTest("2_32_1", 2, 32, 1); 312 RunScheduleAndExecuteTasksTest("2_32_1", 2, 32, 1);
308 } 313 }
309 314
310 } // namespace 315 } // namespace
311 } // namespace cc 316 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/task_graph_runner.cc ('k') | cc/resources/task_graph_runner_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698