summaryrefslogtreecommitdiffstats
path: root/cc/resources/task_graph_runner_perftest.cc
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-23 09:46:50 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-23 09:46:50 +0000
commit00d92d32d28ccbca0241051a628d2ed5f982d1cf (patch)
treef736a9d9b72d97d00ae278beb66dcb7e745d14dd /cc/resources/task_graph_runner_perftest.cc
parent8e1d91e3e45d157f0d279284bc48f47194559d06 (diff)
downloadchromium_src-00d92d32d28ccbca0241051a628d2ed5f982d1cf.zip
chromium_src-00d92d32d28ccbca0241051a628d2ed5f982d1cf.tar.gz
chromium_src-00d92d32d28ccbca0241051a628d2ed5f982d1cf.tar.bz2
Re-land: cc: Remove WorkerPool class and instead use TaskGraphRunner directly.
Removes the unnecessary WorkerPool layer. This makes the job of the TaskGraphRunner more clear and will allow us to remove some complexity and unnecessary heap allocations from the RasterWorkerPool code in follow up patches. Also moves the kNumRasterTasks switch to content/. Refactor only, no changes in behavior. BUG=331844 Review URL: https://codereview.chromium.org/141163019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246554 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/resources/task_graph_runner_perftest.cc')
-rw-r--r--cc/resources/task_graph_runner_perftest.cc221
1 files changed, 221 insertions, 0 deletions
diff --git a/cc/resources/task_graph_runner_perftest.cc b/cc/resources/task_graph_runner_perftest.cc
new file mode 100644
index 0000000..57e5f82
--- /dev/null
+++ b/cc/resources/task_graph_runner_perftest.cc
@@ -0,0 +1,221 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/resources/task_graph_runner.h"
+
+#include "base/time/time.h"
+#include "cc/base/completion_event.h"
+#include "cc/test/lap_timer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+namespace cc {
+namespace {
+
+static const int kTimeLimitMillis = 2000;
+static const int kWarmupRuns = 5;
+static const int kTimeCheckInterval = 10;
+
+class PerfTaskImpl : public internal::Task {
+ public:
+ PerfTaskImpl() {}
+
+ // Overridden from internal::Task:
+ virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {}
+
+ private:
+ virtual ~PerfTaskImpl() {}
+
+ DISALLOW_COPY_AND_ASSIGN(PerfTaskImpl);
+};
+
+class PerfControlTaskImpl : public internal::Task {
+ public:
+ PerfControlTaskImpl() {}
+
+ // Overridden from internal::Task:
+ virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
+ did_start_.Signal();
+ can_finish_.Wait();
+ }
+
+ void WaitForTaskToStartRunning() {
+ did_start_.Wait();
+ }
+
+ void AllowTaskToFinish() {
+ can_finish_.Signal();
+ }
+
+ private:
+ virtual ~PerfControlTaskImpl() {}
+
+ CompletionEvent did_start_;
+ CompletionEvent can_finish_;
+
+ DISALLOW_COPY_AND_ASSIGN(PerfControlTaskImpl);
+};
+
+class TaskGraphRunnerPerfTest : public testing::Test {
+ public:
+ TaskGraphRunnerPerfTest()
+ : timer_(kWarmupRuns,
+ base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+ kTimeCheckInterval) {
+ }
+
+ // Overridden from testing::Test:
+ virtual void SetUp() OVERRIDE {
+ task_graph_runner_ = make_scoped_ptr(
+ new internal::TaskGraphRunner(1, "PerfTest"));
+ namespace_token_ = task_graph_runner_->GetNamespaceToken();
+ }
+ virtual void TearDown() OVERRIDE {
+ task_graph_runner_.reset();
+ }
+
+ void AfterTest(const std::string& test_name) {
+ // Format matches chrome/test/perf/perf_test.h:PrintResult
+ printf("*RESULT %s: %.2f runs/s\n",
+ test_name.c_str(),
+ timer_.LapsPerSecond());
+ }
+
+ void RunScheduleTasksTest(const std::string& test_name,
+ unsigned max_depth,
+ unsigned num_children_per_node) {
+ timer_.Reset();
+ do {
+ scoped_refptr<PerfControlTaskImpl> leaf_task(new PerfControlTaskImpl);
+ ScheduleTasks(NULL, leaf_task.get(), max_depth, num_children_per_node);
+ leaf_task->WaitForTaskToStartRunning();
+ ScheduleTasks(NULL, NULL, 0, 0);
+ leaf_task->AllowTaskToFinish();
+ task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
+ internal::Task::Vector completed_tasks;
+ task_graph_runner_->CollectCompletedTasks(
+ namespace_token_, &completed_tasks);
+ timer_.NextLap();
+ } while (!timer_.HasTimeLimitExpired());
+
+ perf_test::PrintResult("schedule_tasks", "", test_name,
+ timer_.LapsPerSecond(), "runs/s", true);
+ }
+
+ void RunExecuteTasksTest(const std::string& test_name,
+ unsigned max_depth,
+ unsigned num_children_per_node) {
+ timer_.Reset();
+ do {
+ ScheduleTasks(NULL, NULL, max_depth, num_children_per_node);
+ task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
+ internal::Task::Vector completed_tasks;
+ task_graph_runner_->CollectCompletedTasks(
+ namespace_token_, &completed_tasks);
+ timer_.NextLap();
+ } while (!timer_.HasTimeLimitExpired());
+
+ perf_test::PrintResult("execute_tasks", "", test_name,
+ timer_.LapsPerSecond(), "runs/s", true);
+ }
+
+ private:
+ void ScheduleTasks(internal::Task* root_task,
+ internal::Task* leaf_task,
+ unsigned max_depth,
+ unsigned num_children_per_node) {
+ internal::Task::Vector tasks;
+ internal::GraphNode::Map graph;
+
+ scoped_ptr<internal::GraphNode> root_node;
+ if (root_task)
+ root_node = make_scoped_ptr(new internal::GraphNode(root_task, 0u));
+
+ scoped_ptr<internal::GraphNode> leaf_node;
+ if (leaf_task)
+ leaf_node = make_scoped_ptr(new internal::GraphNode(leaf_task, 0u));
+
+ if (max_depth) {
+ BuildTaskGraph(&tasks,
+ &graph,
+ root_node.get(),
+ leaf_node.get(),
+ 0,
+ max_depth,
+ num_children_per_node);
+ }
+
+ if (leaf_node)
+ graph.set(leaf_task, leaf_node.Pass());
+
+ if (root_node)
+ graph.set(root_task, root_node.Pass());
+
+ task_graph_runner_->SetTaskGraph(namespace_token_, &graph);
+
+ tasks_.swap(tasks);
+ }
+
+ void BuildTaskGraph(internal::Task::Vector* tasks,
+ internal::GraphNode::Map* graph,
+ internal::GraphNode* dependent_node,
+ internal::GraphNode* leaf_node,
+ unsigned current_depth,
+ unsigned max_depth,
+ unsigned num_children_per_node) {
+ scoped_refptr<PerfTaskImpl> task(new PerfTaskImpl);
+ scoped_ptr<internal::GraphNode> node(
+ new internal::GraphNode(task.get(), 0u));
+
+ if (current_depth < max_depth) {
+ for (unsigned i = 0; i < num_children_per_node; ++i) {
+ BuildTaskGraph(tasks,
+ graph,
+ node.get(),
+ leaf_node,
+ current_depth + 1,
+ max_depth,
+ num_children_per_node);
+ }
+ } else if (leaf_node) {
+ leaf_node->add_dependent(node.get());
+ node->add_dependency();
+ }
+
+ if (dependent_node) {
+ node->add_dependent(dependent_node);
+ dependent_node->add_dependency();
+ }
+ graph->set(task.get(), node.Pass());
+ tasks->push_back(task.get());
+ }
+
+ scoped_ptr<internal::TaskGraphRunner> task_graph_runner_;
+ internal::NamespaceToken namespace_token_;
+ internal::Task::Vector tasks_;
+ LapTimer timer_;
+};
+
+TEST_F(TaskGraphRunnerPerfTest, ScheduleTasks) {
+ RunScheduleTasksTest("1_10", 1, 10);
+ RunScheduleTasksTest("1_1000", 1, 1000);
+ RunScheduleTasksTest("2_10", 2, 10);
+ RunScheduleTasksTest("5_5", 5, 5);
+ RunScheduleTasksTest("10_2", 10, 2);
+ RunScheduleTasksTest("1000_1", 1000, 1);
+ RunScheduleTasksTest("10_1", 10, 1);
+}
+
+TEST_F(TaskGraphRunnerPerfTest, ExecuteTasks) {
+ RunExecuteTasksTest("1_10", 1, 10);
+ RunExecuteTasksTest("1_1000", 1, 1000);
+ RunExecuteTasksTest("2_10", 2, 10);
+ RunExecuteTasksTest("5_5", 5, 5);
+ RunExecuteTasksTest("10_2", 10, 2);
+ RunExecuteTasksTest("1000_1", 1000, 1);
+ RunExecuteTasksTest("10_1", 10, 1);
+}
+
+} // namespace
+} // namespace cc