X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fcc%2Fresources%2Ftask_graph_runner_perftest.cc;h=71933f58b94e668d4bdbc4e409a3a803f15a175c;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=5e952a3b094c7bc4d47e8c9331f3772c2b8a0e80;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/cc/resources/task_graph_runner_perftest.cc b/src/cc/resources/task_graph_runner_perftest.cc index 5e952a3..71933f5 100644 --- a/src/cc/resources/task_graph_runner_perftest.cc +++ b/src/cc/resources/task_graph_runner_perftest.cc @@ -4,6 +4,8 @@ #include "cc/resources/task_graph_runner.h" +#include + #include "base/time/time.h" #include "cc/base/completion_event.h" #include "cc/test/lap_timer.h" @@ -19,40 +21,21 @@ static const int kTimeCheckInterval = 10; class PerfTaskImpl : public internal::Task { public: + typedef std::vector > Vector; + PerfTaskImpl() {} // Overridden from internal::Task: virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {} + void Reset() { did_run_ = false; } + 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() @@ -63,7 +46,8 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Overridden from testing::Test: virtual void SetUp() OVERRIDE { task_graph_runner_ = - make_scoped_ptr(new internal::TaskGraphRunner(1, "PerfTest")); + make_scoped_ptr(new internal::TaskGraphRunner(0, // 0 worker threads + "PerfTest")); namespace_token_ = task_graph_runner_->GetNamespaceToken(); } virtual void TearDown() OVERRIDE { task_graph_runner_.reset(); } @@ -74,23 +58,66 @@ class TaskGraphRunnerPerfTest : public testing::Test { "*RESULT %s: %.2f runs/s\n", test_name.c_str(), timer_.LapsPerSecond()); } + void RunBuildTaskGraphTest(const std::string& test_name, + int num_top_level_tasks, + int num_tasks, + int num_leaf_tasks) { + PerfTaskImpl::Vector top_level_tasks; + PerfTaskImpl::Vector tasks; + PerfTaskImpl::Vector leaf_tasks; + CreateTasks(num_top_level_tasks, &top_level_tasks); + CreateTasks(num_tasks, &tasks); + CreateTasks(num_leaf_tasks, &leaf_tasks); + + // Avoid unnecessary heap allocations by reusing the same graph. + internal::TaskGraph graph; + + timer_.Reset(); + do { + graph.Reset(); + BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph); + timer_.NextLap(); + } while (!timer_.HasTimeLimitExpired()); + + perf_test::PrintResult("build_task_graph", + "", + test_name, + timer_.LapsPerSecond(), + "runs/s", + true); + } + void RunScheduleTasksTest(const std::string& test_name, - unsigned max_depth, - unsigned num_children_per_node) { + int num_top_level_tasks, + int num_tasks, + int num_leaf_tasks) { + PerfTaskImpl::Vector top_level_tasks; + PerfTaskImpl::Vector tasks; + PerfTaskImpl::Vector leaf_tasks; + CreateTasks(num_top_level_tasks, &top_level_tasks); + CreateTasks(num_tasks, &tasks); + CreateTasks(num_leaf_tasks, &leaf_tasks); + + // Avoid unnecessary heap allocations by reusing the same graph and + // completed tasks vector. + internal::TaskGraph graph; + internal::Task::Vector completed_tasks; + timer_.Reset(); do { - scoped_refptr 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); + graph.Reset(); + BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph); + task_graph_runner_->SetTaskGraph(namespace_token_, &graph); + // Shouldn't be any tasks to collect as we reschedule the same set + // of tasks. + DCHECK_EQ(0u, CollectCompletedTasks(&completed_tasks)); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); + internal::TaskGraph empty; + task_graph_runner_->SetTaskGraph(namespace_token_, &empty); + CollectCompletedTasks(&completed_tasks); + perf_test::PrintResult("schedule_tasks", "", test_name, @@ -99,16 +126,80 @@ class TaskGraphRunnerPerfTest : public testing::Test { true); } - void RunExecuteTasksTest(const std::string& test_name, - unsigned max_depth, - unsigned num_children_per_node) { + void RunScheduleAlternateTasksTest(const std::string& test_name, + int num_top_level_tasks, + int num_tasks, + int num_leaf_tasks) { + const size_t kNumVersions = 2; + PerfTaskImpl::Vector top_level_tasks[kNumVersions]; + PerfTaskImpl::Vector tasks[kNumVersions]; + PerfTaskImpl::Vector leaf_tasks[kNumVersions]; + for (size_t i = 0; i < kNumVersions; ++i) { + CreateTasks(num_top_level_tasks, &top_level_tasks[i]); + CreateTasks(num_tasks, &tasks[i]); + CreateTasks(num_leaf_tasks, &leaf_tasks[i]); + } + + // Avoid unnecessary heap allocations by reusing the same graph and + // completed tasks vector. + internal::TaskGraph graph; + internal::Task::Vector completed_tasks; + + size_t count = 0; 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); + graph.Reset(); + BuildTaskGraph(top_level_tasks[count % kNumVersions], + tasks[count % kNumVersions], + leaf_tasks[count % kNumVersions], + &graph); + task_graph_runner_->SetTaskGraph(namespace_token_, &graph); + CollectCompletedTasks(&completed_tasks); + completed_tasks.clear(); + ++count; + timer_.NextLap(); + } while (!timer_.HasTimeLimitExpired()); + + internal::TaskGraph empty; + task_graph_runner_->SetTaskGraph(namespace_token_, &empty); + CollectCompletedTasks(&completed_tasks); + + perf_test::PrintResult("schedule_alternate_tasks", + "", + test_name, + timer_.LapsPerSecond(), + "runs/s", + true); + } + + void RunScheduleAndExecuteTasksTest(const std::string& test_name, + int num_top_level_tasks, + int num_tasks, + int num_leaf_tasks) { + PerfTaskImpl::Vector top_level_tasks; + PerfTaskImpl::Vector tasks; + PerfTaskImpl::Vector leaf_tasks; + CreateTasks(num_top_level_tasks, &top_level_tasks); + CreateTasks(num_tasks, &tasks); + CreateTasks(num_leaf_tasks, &leaf_tasks); + + // Avoid unnecessary heap allocations by reusing the same graph and + // completed tasks vector. + internal::TaskGraph graph; + internal::Task::Vector completed_tasks; + + timer_.Reset(); + do { + graph.Reset(); + BuildTaskGraph(top_level_tasks, tasks, leaf_tasks, &graph); + task_graph_runner_->SetTaskGraph(namespace_token_, &graph); + while (task_graph_runner_->RunTaskForTesting()) + continue; + CollectCompletedTasks(&completed_tasks); + completed_tasks.clear(); + ResetTasks(&top_level_tasks); + ResetTasks(&tasks); + ResetTasks(&leaf_tasks); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); @@ -117,100 +208,108 @@ class TaskGraphRunnerPerfTest : public testing::Test { } 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 root_node; - if (root_task) - root_node = make_scoped_ptr(new internal::GraphNode(root_task, 0u)); - - scoped_ptr 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()); + void CreateTasks(int num_tasks, PerfTaskImpl::Vector* tasks) { + for (int i = 0; i < num_tasks; ++i) + tasks->push_back(make_scoped_refptr(new PerfTaskImpl)); + } - if (root_node) - graph.set(root_task, root_node.Pass()); + void ResetTasks(PerfTaskImpl::Vector* tasks) { + for (PerfTaskImpl::Vector::iterator it = tasks->begin(); it != tasks->end(); + ++it) { + PerfTaskImpl* task = it->get(); + task->Reset(); + } + } - task_graph_runner_->SetTaskGraph(namespace_token_, &graph); + void BuildTaskGraph(const PerfTaskImpl::Vector& top_level_tasks, + const PerfTaskImpl::Vector& tasks, + const PerfTaskImpl::Vector& leaf_tasks, + internal::TaskGraph* graph) { + DCHECK(graph->nodes.empty()); + DCHECK(graph->edges.empty()); + + for (PerfTaskImpl::Vector::const_iterator it = leaf_tasks.begin(); + it != leaf_tasks.end(); + ++it) { + graph->nodes.push_back(internal::TaskGraph::Node(it->get(), 0u, 0u)); + } - tasks_.swap(tasks); - } + for (PerfTaskImpl::Vector::const_iterator it = tasks.begin(); + it != tasks.end(); + ++it) { + graph->nodes.push_back( + internal::TaskGraph::Node(it->get(), 0u, leaf_tasks.size())); + + for (PerfTaskImpl::Vector::const_iterator leaf_it = leaf_tasks.begin(); + leaf_it != leaf_tasks.end(); + ++leaf_it) { + graph->edges.push_back( + internal::TaskGraph::Edge(leaf_it->get(), it->get())); + } - 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 task(new PerfTaskImpl); - scoped_ptr 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); + for (PerfTaskImpl::Vector::const_iterator top_level_it = + top_level_tasks.begin(); + top_level_it != top_level_tasks.end(); + ++top_level_it) { + graph->edges.push_back( + internal::TaskGraph::Edge(it->get(), top_level_it->get())); } - } 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(); + for (PerfTaskImpl::Vector::const_iterator it = top_level_tasks.begin(); + it != top_level_tasks.end(); + ++it) { + graph->nodes.push_back( + internal::TaskGraph::Node(it->get(), 0u, tasks.size())); } - graph->set(task.get(), node.Pass()); - tasks->push_back(task.get()); + } + + size_t CollectCompletedTasks(internal::Task::Vector* completed_tasks) { + DCHECK(completed_tasks->empty()); + task_graph_runner_->CollectCompletedTasks(namespace_token_, + completed_tasks); + return completed_tasks->size(); } scoped_ptr task_graph_runner_; internal::NamespaceToken namespace_token_; - internal::Task::Vector tasks_; LapTimer timer_; }; +TEST_F(TaskGraphRunnerPerfTest, BuildTaskGraph) { + RunBuildTaskGraphTest("0_1_0", 0, 1, 0); + RunBuildTaskGraphTest("0_32_0", 0, 32, 0); + RunBuildTaskGraphTest("2_1_0", 2, 1, 0); + RunBuildTaskGraphTest("2_32_0", 2, 32, 0); + RunBuildTaskGraphTest("2_1_1", 2, 1, 1); + RunBuildTaskGraphTest("2_32_1", 2, 32, 1); +} + 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); + RunScheduleTasksTest("0_1_0", 0, 1, 0); + RunScheduleTasksTest("0_32_0", 0, 32, 0); + RunScheduleTasksTest("2_1_0", 2, 1, 0); + RunScheduleTasksTest("2_32_0", 2, 32, 0); + RunScheduleTasksTest("2_1_1", 2, 1, 1); + RunScheduleTasksTest("2_32_1", 2, 32, 1); +} + +TEST_F(TaskGraphRunnerPerfTest, ScheduleAlternateTasks) { + RunScheduleAlternateTasksTest("0_1_0", 0, 1, 0); + RunScheduleAlternateTasksTest("0_32_0", 0, 32, 0); + RunScheduleAlternateTasksTest("2_1_0", 2, 1, 0); + RunScheduleAlternateTasksTest("2_32_0", 2, 32, 0); + RunScheduleAlternateTasksTest("2_1_1", 2, 1, 1); + RunScheduleAlternateTasksTest("2_32_1", 2, 32, 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); +TEST_F(TaskGraphRunnerPerfTest, ScheduleAndExecuteTasks) { + RunScheduleAndExecuteTasksTest("0_1_0", 0, 1, 0); + RunScheduleAndExecuteTasksTest("0_32_0", 0, 32, 0); + RunScheduleAndExecuteTasksTest("2_1_0", 2, 1, 0); + RunScheduleAndExecuteTasksTest("2_32_0", 2, 32, 0); + RunScheduleAndExecuteTasksTest("2_1_1", 2, 1, 1); + RunScheduleAndExecuteTasksTest("2_32_1", 2, 32, 1); } } // namespace