1 /*
2  * Copyright (C) 2021 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 <binder/Parcel.h>
18 #include <benchmark/benchmark.h>
19 
20 // Usage: atest binderParcelBenchmark
21 
22 // For static assert(false) we need a template version to avoid early failure.
23 // See: https://stackoverflow.com/questions/51523965/template-dependent-false
24 template <typename T>
25 constexpr bool dependent_false_v = false;
26 
27 template <template <typename ...> class V, typename T, typename... Args>
writeVector(android::Parcel & p,const V<T,Args...> & v)28 void writeVector(android::Parcel &p, const V<T, Args...> &v) {
29     if constexpr (std::is_same_v<T, bool>) {
30         p.writeBoolVector(v);
31     } else if constexpr (std::is_same_v<T, uint8_t>) {
32         p.writeByteVector(v);
33     } else if constexpr (std::is_same_v<T, char16_t>) {
34         p.writeCharVector(v);
35     } else if constexpr (std::is_same_v<T, int32_t>) {
36         p.writeInt32Vector(v);
37     } else if constexpr (std::is_same_v<T, int64_t>) {
38         p.writeInt64Vector(v);
39     } else {
40         static_assert(dependent_false_v<V<T>>);
41     }
42 }
43 
44 template <template <typename ...> class V, typename T, typename... Args>
readVector(android::Parcel & p,V<T,Args...> * v)45 void readVector(android::Parcel &p, V<T, Args...> *v) {
46     if constexpr (std::is_same_v<T, bool>) {
47         p.readBoolVector(v);
48     } else if constexpr (std::is_same_v<T, uint8_t>) {
49         p.readByteVector(v);
50     } else if constexpr (std::is_same_v<T, char16_t>) {
51         p.readCharVector(v);
52     } else if constexpr (std::is_same_v<T, int32_t>) {
53         p.readInt32Vector(v);
54     } else if constexpr (std::is_same_v<T, int64_t>) {
55         p.readInt64Vector(v);
56     } else {
57         static_assert(dependent_false_v<V<T>>);
58     }
59 }
60 
61 // Construct a series of args { 1 << 0, 1 << 1, ..., 1 << 10 }
VectorArgs(benchmark::internal::Benchmark * b)62 static void VectorArgs(benchmark::internal::Benchmark* b) {
63     for (int i = 0; i < 10; ++i) {
64         b->Args({1 << i});
65     }
66 }
67 
68 template <typename T>
BM_ParcelVector(benchmark::State & state)69 static void BM_ParcelVector(benchmark::State& state) {
70     const size_t elements = state.range(0);
71 
72     std::vector<T> v1(elements);
73     std::vector<T> v2(elements);
74     android::Parcel p;
75     while (state.KeepRunning()) {
76         p.setDataPosition(0);
77         writeVector(p, v1);
78 
79         p.setDataPosition(0);
80         readVector(p, &v2);
81 
82         benchmark::DoNotOptimize(v2[0]);
83         benchmark::ClobberMemory();
84     }
85     state.SetComplexityN(elements);
86 }
87 
88 /*
89   Parcel vector write than read.
90   The read and write vectors are fixed, no resizing required.
91 
92   Results on Crosshatch Pixel 3XL
93 
94   #BM_BoolVector/1         44 ns      44 ns     15630626
95   #BM_BoolVector/2         54 ns      54 ns     12900340
96   #BM_BoolVector/4         73 ns      72 ns      9749841
97   #BM_BoolVector/8        107 ns     107 ns      6503326
98   #BM_BoolVector/16       186 ns     185 ns      3773627
99   #BM_BoolVector/32       337 ns     336 ns      2083877
100   #BM_BoolVector/64       607 ns     605 ns      1154113
101   #BM_BoolVector/128     1155 ns    1151 ns       608128
102   #BM_BoolVector/256     2259 ns    2253 ns       310973
103   #BM_BoolVector/512     4469 ns    4455 ns       157277
104   #BM_ByteVector/1         41 ns      41 ns     16837425
105   #BM_ByteVector/2         41 ns      41 ns     16820726
106   #BM_ByteVector/4         38 ns      38 ns     18217813
107   #BM_ByteVector/8         38 ns      38 ns     18290298
108   #BM_ByteVector/16        38 ns      38 ns     18117817
109   #BM_ByteVector/32        38 ns      38 ns     18172385
110   #BM_ByteVector/64        41 ns      41 ns     16950055
111   #BM_ByteVector/128       53 ns      53 ns     13170749
112   #BM_ByteVector/256       69 ns      69 ns     10113626
113   #BM_ByteVector/512      106 ns     106 ns      6561936
114   #BM_CharVector/1         38 ns      38 ns     18074831
115   #BM_CharVector/2         40 ns      40 ns     17206266
116   #BM_CharVector/4         50 ns      50 ns     13785944
117   #BM_CharVector/8         67 ns      67 ns     10223316
118   #BM_CharVector/16        96 ns      96 ns      7297285
119   #BM_CharVector/32       156 ns     155 ns      4484845
120   #BM_CharVector/64       277 ns     276 ns      2536003
121   #BM_CharVector/128      520 ns     518 ns      1347070
122   #BM_CharVector/256     1006 ns    1003 ns       695952
123   #BM_CharVector/512     1976 ns    1970 ns       354673
124   #BM_Int32Vector/1        41 ns      41 ns     16951262
125   #BM_Int32Vector/2        41 ns      41 ns     16916883
126   #BM_Int32Vector/4        41 ns      41 ns     16761373
127   #BM_Int32Vector/8        42 ns      42 ns     16553179
128   #BM_Int32Vector/16       43 ns      43 ns     16200362
129   #BM_Int32Vector/32       55 ns      54 ns     12724454
130   #BM_Int32Vector/64       70 ns      69 ns     10049223
131   #BM_Int32Vector/128     107 ns     107 ns      6525796
132   #BM_Int32Vector/256     179 ns     178 ns      3922563
133   #BM_Int32Vector/512     324 ns     323 ns      2160653
134   #BM_Int64Vector/1        41 ns      41 ns     16909470
135   #BM_Int64Vector/2        41 ns      41 ns     16740788
136   #BM_Int64Vector/4        42 ns      42 ns     16564197
137   #BM_Int64Vector/8        43 ns      42 ns     16284082
138   #BM_Int64Vector/16       54 ns      54 ns     12839474
139   #BM_Int64Vector/32       69 ns      69 ns     10011010
140   #BM_Int64Vector/64      107 ns     106 ns      6557956
141   #BM_Int64Vector/128     177 ns     177 ns      3925618
142   #BM_Int64Vector/256     324 ns     323 ns      2163321
143   #BM_Int64Vector/512     613 ns     611 ns      1140418
144 */
145 
BM_BoolVector(benchmark::State & state)146 static void BM_BoolVector(benchmark::State& state) {
147     BM_ParcelVector<bool>(state);
148 }
149 
BM_ByteVector(benchmark::State & state)150 static void BM_ByteVector(benchmark::State& state) {
151     BM_ParcelVector<uint8_t>(state);
152 }
153 
BM_CharVector(benchmark::State & state)154 static void BM_CharVector(benchmark::State& state) {
155     BM_ParcelVector<char16_t>(state);
156 }
157 
BM_Int32Vector(benchmark::State & state)158 static void BM_Int32Vector(benchmark::State& state) {
159     BM_ParcelVector<int32_t>(state);
160 }
161 
BM_Int64Vector(benchmark::State & state)162 static void BM_Int64Vector(benchmark::State& state) {
163     BM_ParcelVector<int64_t>(state);
164 }
165 
166 BENCHMARK(BM_BoolVector)->Apply(VectorArgs);
167 BENCHMARK(BM_ByteVector)->Apply(VectorArgs);
168 BENCHMARK(BM_CharVector)->Apply(VectorArgs);
169 BENCHMARK(BM_Int32Vector)->Apply(VectorArgs);
170 BENCHMARK(BM_Int64Vector)->Apply(VectorArgs);
171 
172 BENCHMARK_MAIN();
173