blob: 67cb428102d36d0e72a3e829eea56c87e135572f [file] [log] [blame]
Chris Craikb251a2f2016-02-08 19:36:46 +00001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
John Reck0418afa32016-03-07 13:24:25 -080017#include <benchmark/benchmark.h>
Chris Craikb251a2f2016-02-08 19:36:46 +000018
19#include "thread/Task.h"
20#include "thread/TaskManager.h"
21#include "thread/TaskProcessor.h"
John Reckf8441e62017-10-23 13:10:41 -070022#include "thread/ThreadBase.h"
Chris Craikb251a2f2016-02-08 19:36:46 +000023
John Reckf8441e62017-10-23 13:10:41 -070024#include <atomic>
Chris Craikb251a2f2016-02-08 19:36:46 +000025#include <vector>
26
27using namespace android;
28using namespace android::uirenderer;
29
30class TrivialTask : public Task<char> {};
31
32class TrivialProcessor : public TaskProcessor<char> {
33public:
Chih-Hung Hsiehd53e3be2016-05-03 10:02:51 -070034 explicit TrivialProcessor(TaskManager* manager)
Chris Craikb251a2f2016-02-08 19:36:46 +000035 : TaskProcessor(manager) {}
36 virtual ~TrivialProcessor() {}
37 virtual void onProcess(const sp<Task<char> >& task) override {
38 TrivialTask* t = static_cast<TrivialTask*>(task.get());
39 t->setResult(reinterpret_cast<intptr_t>(t) % 16 == 0 ? 'a' : 'b');
40 }
41};
42
John Reckf8441e62017-10-23 13:10:41 -070043class TestThread : public ThreadBase, public virtual RefBase {};
44
John Reck0418afa32016-03-07 13:24:25 -080045void BM_TaskManager_allocateTask(benchmark::State& state) {
Chris Craikb251a2f2016-02-08 19:36:46 +000046 std::vector<sp<TrivialTask> > tasks;
John Reck0418afa32016-03-07 13:24:25 -080047 tasks.reserve(state.max_iterations);
Chris Craikb251a2f2016-02-08 19:36:46 +000048
John Reck0418afa32016-03-07 13:24:25 -080049 while (state.KeepRunning()) {
Chris Craikb251a2f2016-02-08 19:36:46 +000050 tasks.emplace_back(new TrivialTask);
John Reck0418afa32016-03-07 13:24:25 -080051 benchmark::DoNotOptimize(tasks.back());
Chris Craikb251a2f2016-02-08 19:36:46 +000052 }
Chris Craikb251a2f2016-02-08 19:36:46 +000053}
John Reck0418afa32016-03-07 13:24:25 -080054BENCHMARK(BM_TaskManager_allocateTask);
Chris Craikb251a2f2016-02-08 19:36:46 +000055
John Reck0418afa32016-03-07 13:24:25 -080056void BM_TaskManager_enqueueTask(benchmark::State& state) {
Chris Craikb251a2f2016-02-08 19:36:46 +000057 TaskManager taskManager;
58 sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
59 std::vector<sp<TrivialTask> > tasks;
John Reck0418afa32016-03-07 13:24:25 -080060 tasks.reserve(state.max_iterations);
Chris Craikb251a2f2016-02-08 19:36:46 +000061
John Reck0418afa32016-03-07 13:24:25 -080062 while (state.KeepRunning()) {
Chris Craikb251a2f2016-02-08 19:36:46 +000063 tasks.emplace_back(new TrivialTask);
John Reck0418afa32016-03-07 13:24:25 -080064 benchmark::DoNotOptimize(tasks.back());
Chris Craikb251a2f2016-02-08 19:36:46 +000065 processor->add(tasks.back());
66 }
Chris Craikb251a2f2016-02-08 19:36:46 +000067
68 for (sp<TrivialTask>& task : tasks) {
69 task->getResult();
70 }
71}
John Reck0418afa32016-03-07 13:24:25 -080072BENCHMARK(BM_TaskManager_enqueueTask);
Chris Craikb251a2f2016-02-08 19:36:46 +000073
John Reck0418afa32016-03-07 13:24:25 -080074void BM_TaskManager_enqueueRunDeleteTask(benchmark::State& state) {
Chris Craikb251a2f2016-02-08 19:36:46 +000075 TaskManager taskManager;
76 sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
77 std::vector<sp<TrivialTask> > tasks;
John Reck0418afa32016-03-07 13:24:25 -080078 tasks.reserve(state.max_iterations);
Chris Craikb251a2f2016-02-08 19:36:46 +000079
John Reck0418afa32016-03-07 13:24:25 -080080 while (state.KeepRunning()) {
Chris Craikb251a2f2016-02-08 19:36:46 +000081 tasks.emplace_back(new TrivialTask);
John Reck0418afa32016-03-07 13:24:25 -080082 benchmark::DoNotOptimize(tasks.back());
Chris Craikb251a2f2016-02-08 19:36:46 +000083 processor->add(tasks.back());
84 }
John Reck0418afa32016-03-07 13:24:25 -080085 state.ResumeTiming();
Chris Craikb251a2f2016-02-08 19:36:46 +000086 for (sp<TrivialTask>& task : tasks) {
John Reck0418afa32016-03-07 13:24:25 -080087 benchmark::DoNotOptimize(task->getResult());
Chris Craikb251a2f2016-02-08 19:36:46 +000088 }
89 tasks.clear();
John Reck0418afa32016-03-07 13:24:25 -080090 state.PauseTiming();
Chris Craikb251a2f2016-02-08 19:36:46 +000091}
John Reck0418afa32016-03-07 13:24:25 -080092BENCHMARK(BM_TaskManager_enqueueRunDeleteTask);
John Reckf8441e62017-10-23 13:10:41 -070093
94void BM_Thread_enqueueTask(benchmark::State& state) {
95 sp<TestThread> thread{new TestThread};
96 thread->start();
97
98 atomic_int counter(0);
99 int expected = 0;
100 while (state.KeepRunning()) {
101 expected++;
102 thread->queue().post([&counter](){
103 counter++;
104 });
105 }
106 thread->queue().runSync([](){});
107
108 thread->requestExit();
109 thread->join();
110 if (counter != expected) {
111 printf("Ran %d lambads, should have been %d\n", counter.load(), expected);
112 }
113}
114BENCHMARK(BM_Thread_enqueueTask);
115
116void BM_Thread_enqueueRunDeleteTask(benchmark::State& state) {
117 sp<TestThread> thread{new TestThread};
118 thread->start();
119 std::vector<std::future<int>> tasks;
120 tasks.reserve(state.max_iterations);
121
122 int expected = 0;
123 while (state.KeepRunning()) {
124 tasks.emplace_back(thread->queue().async([expected]() -> int {
125 return expected + 1;
126 }));
127 expected++;
128 }
129 state.ResumeTiming();
130 expected = 0;
131 for (auto& future : tasks) {
132 if (future.get() != ++expected) {
133 printf("Mismatch expected %d vs. observed %d\n", expected, future.get());
134 }
135 }
136 tasks.clear();
137 state.PauseTiming();
138}
139BENCHMARK(BM_Thread_enqueueRunDeleteTask);