• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include <benchmark/benchmark.h>
18 
19 #include "thread/Task.h"
20 #include "thread/TaskManager.h"
21 #include "thread/TaskProcessor.h"
22 #include "thread/ThreadBase.h"
23 
24 #include <atomic>
25 #include <vector>
26 
27 using namespace android;
28 using namespace android::uirenderer;
29 
30 class TrivialTask : public Task<char> {};
31 
32 class TrivialProcessor : public TaskProcessor<char> {
33 public:
TrivialProcessor(TaskManager * manager)34     explicit TrivialProcessor(TaskManager* manager) : TaskProcessor(manager) {}
~TrivialProcessor()35     virtual ~TrivialProcessor() {}
onProcess(const sp<Task<char>> & task)36     virtual void onProcess(const sp<Task<char>>& task) override {
37         TrivialTask* t = static_cast<TrivialTask*>(task.get());
38         t->setResult(reinterpret_cast<intptr_t>(t) % 16 == 0 ? 'a' : 'b');
39     }
40 };
41 
42 class TestThread : public ThreadBase, public virtual RefBase {};
43 
BM_TaskManager_allocateTask(benchmark::State & state)44 void BM_TaskManager_allocateTask(benchmark::State& state) {
45     std::vector<sp<TrivialTask>> tasks;
46     tasks.reserve(state.max_iterations);
47 
48     while (state.KeepRunning()) {
49         tasks.emplace_back(new TrivialTask);
50         benchmark::DoNotOptimize(tasks.back());
51     }
52 }
53 BENCHMARK(BM_TaskManager_allocateTask);
54 
BM_TaskManager_enqueueTask(benchmark::State & state)55 void BM_TaskManager_enqueueTask(benchmark::State& state) {
56     TaskManager taskManager;
57     sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
58     std::vector<sp<TrivialTask>> tasks;
59     tasks.reserve(state.max_iterations);
60 
61     while (state.KeepRunning()) {
62         tasks.emplace_back(new TrivialTask);
63         benchmark::DoNotOptimize(tasks.back());
64         processor->add(tasks.back());
65     }
66 
67     for (sp<TrivialTask>& task : tasks) {
68         task->getResult();
69     }
70 }
71 BENCHMARK(BM_TaskManager_enqueueTask);
72 
BM_TaskManager_enqueueRunDeleteTask(benchmark::State & state)73 void BM_TaskManager_enqueueRunDeleteTask(benchmark::State& state) {
74     TaskManager taskManager;
75     sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
76     std::vector<sp<TrivialTask>> tasks;
77     tasks.reserve(state.max_iterations);
78 
79     while (state.KeepRunning()) {
80         tasks.emplace_back(new TrivialTask);
81         benchmark::DoNotOptimize(tasks.back());
82         processor->add(tasks.back());
83     }
84     state.ResumeTiming();
85     for (sp<TrivialTask>& task : tasks) {
86         benchmark::DoNotOptimize(task->getResult());
87     }
88     tasks.clear();
89     state.PauseTiming();
90 }
91 BENCHMARK(BM_TaskManager_enqueueRunDeleteTask);
92 
BM_Thread_enqueueTask(benchmark::State & state)93 void BM_Thread_enqueueTask(benchmark::State& state) {
94     sp<TestThread> thread{new TestThread};
95     thread->start();
96 
97     atomic_int counter(0);
98     int expected = 0;
99     while (state.KeepRunning()) {
100         expected++;
101         thread->queue().post([&counter]() { counter++; });
102     }
103     thread->queue().runSync([]() {});
104 
105     thread->requestExit();
106     thread->join();
107     if (counter != expected) {
108         printf("Ran %d lambads, should have been %d\n", counter.load(), expected);
109     }
110 }
111 BENCHMARK(BM_Thread_enqueueTask);
112 
BM_Thread_enqueueRunDeleteTask(benchmark::State & state)113 void BM_Thread_enqueueRunDeleteTask(benchmark::State& state) {
114     sp<TestThread> thread{new TestThread};
115     thread->start();
116     std::vector<std::future<int>> tasks;
117     tasks.reserve(state.max_iterations);
118 
119     int expected = 0;
120     while (state.KeepRunning()) {
121         tasks.emplace_back(thread->queue().async([expected]() -> int { return expected + 1; }));
122         expected++;
123     }
124     state.ResumeTiming();
125     expected = 0;
126     for (auto& future : tasks) {
127         if (future.get() != ++expected) {
128             printf("Mismatch expected %d vs. observed %d\n", expected, future.get());
129         }
130     }
131     tasks.clear();
132     state.PauseTiming();
133 }
134 BENCHMARK(BM_Thread_enqueueRunDeleteTask);