xref: /aosp_15_r20/external/perfetto/src/profiling/memory/client_api_benchmark.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 // Copyright (C) 2021 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <benchmark/benchmark.h>
16 
17 #include "perfetto/heap_profile.h"
18 #include "src/profiling/memory/heap_profile_internal.h"
19 
20 #include "src/profiling/memory/client.h"
21 #include "src/profiling/memory/client_api_factory.h"
22 
23 namespace perfetto {
24 namespace profiling {
25 
26 namespace {
GetHeapId()27 uint32_t GetHeapId() {
28   static uint32_t heap_id =
29       AHeapProfile_registerHeap(AHeapInfo_create("dev.perfetto.benchmark"));
30   return heap_id;
31 }
32 
33 ClientConfiguration g_client_config;
34 int g_shmem_fd;
35 
GlobalServerSocket()36 base::UnixSocketRaw& GlobalServerSocket() {
37   static base::UnixSocketRaw* srv_sock = new base::UnixSocketRaw;
38   return *srv_sock;
39 }
40 
DisconnectGlobalServerSocket()41 void DisconnectGlobalServerSocket() {
42   base::UnixSocketRaw destroy;
43   std::swap(destroy, GlobalServerSocket());
44 }
45 
46 }  // namespace
47 
48 // This is called by AHeapProfile_initSession (client_api.cc) to construct a
49 // client. The Client API requires to be linked against another compliation
50 // unit that provides this function. This way, it can be used in different
51 // circumstances (central heapprofd, fork heapprofd) and be agnostic about the
52 // details. This is is used to create a test Client here.
StartHeapprofdIfStatic()53 void StartHeapprofdIfStatic() {}
ConstructClient(UnhookedAllocator<perfetto::profiling::Client> unhooked_allocator)54 std::shared_ptr<Client> ConstructClient(
55     UnhookedAllocator<perfetto::profiling::Client> unhooked_allocator) {
56   base::UnixSocketRaw cli_sock;
57   base::UnixSocketRaw& srv_sock = GlobalServerSocket();
58   std::tie(cli_sock, srv_sock) = base::UnixSocketRaw::CreatePairPosix(
59       base::SockFamily::kUnix, base::SockType::kStream);
60   auto ringbuf = SharedRingBuffer::Create(8 * 1048576);
61   ringbuf->InfiniteBufferForTesting();
62   PERFETTO_CHECK(ringbuf);
63   PERFETTO_CHECK(cli_sock);
64   PERFETTO_CHECK(srv_sock);
65   g_shmem_fd = ringbuf->fd();
66   return std::allocate_shared<Client>(unhooked_allocator, std::move(cli_sock),
67                                       g_client_config, std::move(*ringbuf),
68                                       getpid(), GetMainThreadStackRange());
69 }
70 
BM_ClientApiOneTenthAllocation(benchmark::State & state)71 static void BM_ClientApiOneTenthAllocation(benchmark::State& state) {
72   const uint32_t heap_id = GetHeapId();
73 
74   ClientConfiguration client_config{};
75   client_config.default_interval = 32000;
76   client_config.all_heaps = true;
77   g_client_config = client_config;
78   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
79 
80   PERFETTO_CHECK(g_shmem_fd);
81   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
82 
83   for (auto _ : state) {
84     AHeapProfile_reportAllocation(heap_id, 0x123, 3200);
85   }
86   DisconnectGlobalServerSocket();
87   ringbuf->SetShuttingDown();
88 }
89 
90 BENCHMARK(BM_ClientApiOneTenthAllocation);
91 
BM_ClientApiOneHundrethAllocation(benchmark::State & state)92 static void BM_ClientApiOneHundrethAllocation(benchmark::State& state) {
93   const uint32_t heap_id = GetHeapId();
94 
95   ClientConfiguration client_config{};
96   client_config.default_interval = 32000;
97   client_config.all_heaps = true;
98   g_client_config = client_config;
99   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
100 
101   PERFETTO_CHECK(g_shmem_fd);
102   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
103 
104   for (auto _ : state) {
105     AHeapProfile_reportAllocation(heap_id, 0x123, 320);
106   }
107   DisconnectGlobalServerSocket();
108   ringbuf->SetShuttingDown();
109 }
110 
111 BENCHMARK(BM_ClientApiOneHundrethAllocation);
112 
BM_ClientApiAlmostNoAllocation(benchmark::State & state)113 static void BM_ClientApiAlmostNoAllocation(benchmark::State& state) {
114   const uint32_t heap_id = GetHeapId();
115 
116   ClientConfiguration client_config{};
117   client_config.default_interval = 10000000000000000;
118   client_config.all_heaps = true;
119   g_client_config = client_config;
120   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
121 
122   PERFETTO_CHECK(g_shmem_fd);
123   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
124 
125   for (auto _ : state) {
126     AHeapProfile_reportAllocation(heap_id, 0x123, 1);
127   }
128   DisconnectGlobalServerSocket();
129   ringbuf->SetShuttingDown();
130 }
131 
132 BENCHMARK(BM_ClientApiAlmostNoAllocation);
133 
BM_ClientApiSample(benchmark::State & state)134 static void BM_ClientApiSample(benchmark::State& state) {
135   const uint32_t heap_id = GetHeapId();
136 
137   ClientConfiguration client_config{};
138   client_config.default_interval = 32000;
139   client_config.all_heaps = true;
140   g_client_config = client_config;
141   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
142 
143   PERFETTO_CHECK(g_shmem_fd);
144   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
145 
146   for (auto _ : state) {
147     AHeapProfile_reportSample(heap_id, 0x123, 20);
148   }
149   DisconnectGlobalServerSocket();
150   ringbuf->SetShuttingDown();
151 }
152 
153 BENCHMARK(BM_ClientApiSample);
154 
BM_ClientApiDisabledHeapAllocation(benchmark::State & state)155 static void BM_ClientApiDisabledHeapAllocation(benchmark::State& state) {
156   const uint32_t heap_id = GetHeapId();
157 
158   ClientConfiguration client_config{};
159   client_config.default_interval = 32000;
160   client_config.all_heaps = false;
161   g_client_config = client_config;
162   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
163 
164   PERFETTO_CHECK(g_shmem_fd);
165   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
166 
167   for (auto _ : state) {
168     AHeapProfile_reportAllocation(heap_id, 0x123, 20);
169   }
170   DisconnectGlobalServerSocket();
171   ringbuf->SetShuttingDown();
172 }
173 
174 BENCHMARK(BM_ClientApiDisabledHeapAllocation);
175 
BM_ClientApiDisabledHeapFree(benchmark::State & state)176 static void BM_ClientApiDisabledHeapFree(benchmark::State& state) {
177   const uint32_t heap_id = GetHeapId();
178 
179   ClientConfiguration client_config{};
180   client_config.default_interval = 32000;
181   client_config.all_heaps = false;
182   g_client_config = client_config;
183   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
184 
185   PERFETTO_CHECK(g_shmem_fd);
186   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
187 
188   for (auto _ : state) {
189     AHeapProfile_reportFree(heap_id, 0x123);
190   }
191   DisconnectGlobalServerSocket();
192   ringbuf->SetShuttingDown();
193 }
194 
195 BENCHMARK(BM_ClientApiDisabledHeapFree);
196 
BM_ClientApiEnabledHeapFree(benchmark::State & state)197 static void BM_ClientApiEnabledHeapFree(benchmark::State& state) {
198   const uint32_t heap_id = GetHeapId();
199 
200   ClientConfiguration client_config{};
201   client_config.default_interval = 32000;
202   client_config.all_heaps = true;
203   g_client_config = client_config;
204   PERFETTO_CHECK(AHeapProfile_initSession(malloc, free));
205 
206   PERFETTO_CHECK(g_shmem_fd);
207   auto ringbuf = SharedRingBuffer::Attach(base::ScopedFile(dup(g_shmem_fd)));
208 
209   for (auto _ : state) {
210     AHeapProfile_reportFree(heap_id, 0x123);
211   }
212   DisconnectGlobalServerSocket();
213   ringbuf->SetShuttingDown();
214 }
215 
216 BENCHMARK(BM_ClientApiEnabledHeapFree);
217 
BM_ClientApiMallocFree(benchmark::State & state)218 static void BM_ClientApiMallocFree(benchmark::State& state) {
219   for (auto _ : state) {
220     volatile char* x = static_cast<char*>(malloc(100));
221     if (x) {
222       x[0] = 'x';
223       free(const_cast<char*>(x));
224     }
225   }
226 }
227 
228 BENCHMARK(BM_ClientApiMallocFree);
229 
230 }  // namespace profiling
231 }  // namespace perfetto
232