1*6dbdd20aSAndroid Build Coastguard Worker // Copyright (C) 2020 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker //
3*6dbdd20aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker //
7*6dbdd20aSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker //
9*6dbdd20aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker // limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing.h"
18*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/test_event.pbzero.h"
19*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace.pbzero.h"
20*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace_packet.pbzero.h"
21*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/log_message.pbzero.h"
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_CATEGORIES(perfetto::Category("benchmark"));
24*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_TRACK_EVENT_STATIC_STORAGE();
25*6dbdd20aSAndroid Build Coastguard Worker
26*6dbdd20aSAndroid Build Coastguard Worker namespace {
27*6dbdd20aSAndroid Build Coastguard Worker
28*6dbdd20aSAndroid Build Coastguard Worker class BenchmarkDataSource : public perfetto::DataSource<BenchmarkDataSource> {
29*6dbdd20aSAndroid Build Coastguard Worker public:
OnSetup(const SetupArgs &)30*6dbdd20aSAndroid Build Coastguard Worker void OnSetup(const SetupArgs&) override {}
OnStart(const StartArgs &)31*6dbdd20aSAndroid Build Coastguard Worker void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)32*6dbdd20aSAndroid Build Coastguard Worker void OnStop(const StopArgs&) override {}
33*6dbdd20aSAndroid Build Coastguard Worker };
34*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingDataSourceDisabled(benchmark::State & state)35*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingDataSourceDisabled(benchmark::State& state) {
36*6dbdd20aSAndroid Build Coastguard Worker while (state.KeepRunning()) {
37*6dbdd20aSAndroid Build Coastguard Worker BenchmarkDataSource::Trace([&](BenchmarkDataSource::TraceContext) {});
38*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
39*6dbdd20aSAndroid Build Coastguard Worker }
40*6dbdd20aSAndroid Build Coastguard Worker }
41*6dbdd20aSAndroid Build Coastguard Worker
StartTracing(const std::string & data_source_name)42*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<perfetto::TracingSession> StartTracing(
43*6dbdd20aSAndroid Build Coastguard Worker const std::string& data_source_name) {
44*6dbdd20aSAndroid Build Coastguard Worker perfetto::TracingInitArgs args;
45*6dbdd20aSAndroid Build Coastguard Worker args.backends = perfetto::kInProcessBackend;
46*6dbdd20aSAndroid Build Coastguard Worker perfetto::Tracing::Initialize(args);
47*6dbdd20aSAndroid Build Coastguard Worker
48*6dbdd20aSAndroid Build Coastguard Worker perfetto::DataSourceDescriptor dsd;
49*6dbdd20aSAndroid Build Coastguard Worker dsd.set_name("benchmark");
50*6dbdd20aSAndroid Build Coastguard Worker BenchmarkDataSource::Register(dsd);
51*6dbdd20aSAndroid Build Coastguard Worker perfetto::TrackEvent::Register();
52*6dbdd20aSAndroid Build Coastguard Worker
53*6dbdd20aSAndroid Build Coastguard Worker perfetto::TraceConfig cfg;
54*6dbdd20aSAndroid Build Coastguard Worker cfg.add_buffers()->set_size_kb(1024);
55*6dbdd20aSAndroid Build Coastguard Worker auto* ds_cfg = cfg.add_data_sources()->mutable_config();
56*6dbdd20aSAndroid Build Coastguard Worker ds_cfg->set_name(data_source_name);
57*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session =
58*6dbdd20aSAndroid Build Coastguard Worker perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
59*6dbdd20aSAndroid Build Coastguard Worker tracing_session->Setup(cfg);
60*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StartBlocking();
61*6dbdd20aSAndroid Build Coastguard Worker return tracing_session;
62*6dbdd20aSAndroid Build Coastguard Worker }
63*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingDataSourceLambda(benchmark::State & state)64*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingDataSourceLambda(benchmark::State& state) {
65*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = StartTracing("benchmark");
66*6dbdd20aSAndroid Build Coastguard Worker
67*6dbdd20aSAndroid Build Coastguard Worker while (state.KeepRunning()) {
68*6dbdd20aSAndroid Build Coastguard Worker BenchmarkDataSource::Trace([&](BenchmarkDataSource::TraceContext ctx) {
69*6dbdd20aSAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
70*6dbdd20aSAndroid Build Coastguard Worker packet->set_timestamp(42);
71*6dbdd20aSAndroid Build Coastguard Worker packet->set_for_testing()->set_str("benchmark");
72*6dbdd20aSAndroid Build Coastguard Worker });
73*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
74*6dbdd20aSAndroid Build Coastguard Worker }
75*6dbdd20aSAndroid Build Coastguard Worker
76*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StopBlocking();
77*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(!tracing_session->ReadTraceBlocking().empty());
78*6dbdd20aSAndroid Build Coastguard Worker }
79*6dbdd20aSAndroid Build Coastguard Worker
80*6dbdd20aSAndroid Build Coastguard Worker // Parses `trace` and returns the size of the first trace packet that contains
81*6dbdd20aSAndroid Build Coastguard Worker // `for_testing()`.
GetForTestingPacketSizeFromTrace(const std::vector<char> & trace)82*6dbdd20aSAndroid Build Coastguard Worker size_t GetForTestingPacketSizeFromTrace(const std::vector<char>& trace) {
83*6dbdd20aSAndroid Build Coastguard Worker size_t packet_size = 0;
84*6dbdd20aSAndroid Build Coastguard Worker perfetto::protos::pbzero::Trace::Decoder decoder(
85*6dbdd20aSAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(trace.data()), trace.size());
86*6dbdd20aSAndroid Build Coastguard Worker for (auto packet = decoder.packet(); packet; packet++) {
87*6dbdd20aSAndroid Build Coastguard Worker perfetto::protos::pbzero::TracePacket::Decoder packet_decoder(*packet);
88*6dbdd20aSAndroid Build Coastguard Worker
89*6dbdd20aSAndroid Build Coastguard Worker if (packet_decoder.has_for_testing()) {
90*6dbdd20aSAndroid Build Coastguard Worker packet_size = packet->size();
91*6dbdd20aSAndroid Build Coastguard Worker break;
92*6dbdd20aSAndroid Build Coastguard Worker }
93*6dbdd20aSAndroid Build Coastguard Worker }
94*6dbdd20aSAndroid Build Coastguard Worker return packet_size;
95*6dbdd20aSAndroid Build Coastguard Worker }
96*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingDataSourceLambdaDifferentPacketSize(benchmark::State & state)97*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingDataSourceLambdaDifferentPacketSize(
98*6dbdd20aSAndroid Build Coastguard Worker benchmark::State& state) {
99*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = StartTracing("benchmark");
100*6dbdd20aSAndroid Build Coastguard Worker // The number of string fields added in the nested submessage. This controls
101*6dbdd20aSAndroid Build Coastguard Worker // the size of the trace packet (reported by the "PacketSize" counter).
102*6dbdd20aSAndroid Build Coastguard Worker const size_t kNumFields = static_cast<size_t>(state.range(0));
103*6dbdd20aSAndroid Build Coastguard Worker
104*6dbdd20aSAndroid Build Coastguard Worker for (auto _ : state) {
105*6dbdd20aSAndroid Build Coastguard Worker BenchmarkDataSource::Trace([&](BenchmarkDataSource::TraceContext ctx) {
106*6dbdd20aSAndroid Build Coastguard Worker auto packet = ctx.NewTracePacket();
107*6dbdd20aSAndroid Build Coastguard Worker auto* payload = packet->set_for_testing()->set_payload();
108*6dbdd20aSAndroid Build Coastguard Worker for (size_t i = 0; i < kNumFields; i++) {
109*6dbdd20aSAndroid Build Coastguard Worker payload->add_str("ABCDEFGH");
110*6dbdd20aSAndroid Build Coastguard Worker }
111*6dbdd20aSAndroid Build Coastguard Worker });
112*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
113*6dbdd20aSAndroid Build Coastguard Worker }
114*6dbdd20aSAndroid Build Coastguard Worker
115*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StopBlocking();
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Worker std::vector<char> trace = tracing_session->ReadTraceBlocking();
118*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(!trace.empty());
119*6dbdd20aSAndroid Build Coastguard Worker state.counters["PacketSize"] =
120*6dbdd20aSAndroid Build Coastguard Worker static_cast<double>(GetForTestingPacketSizeFromTrace(trace));
121*6dbdd20aSAndroid Build Coastguard Worker }
122*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingTrackEventDisabled(benchmark::State & state)123*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingTrackEventDisabled(benchmark::State& state) {
124*6dbdd20aSAndroid Build Coastguard Worker while (state.KeepRunning()) {
125*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT_BEGIN("benchmark", "DisabledEvent");
126*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
127*6dbdd20aSAndroid Build Coastguard Worker }
128*6dbdd20aSAndroid Build Coastguard Worker }
129*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingTrackEventBasic(benchmark::State & state)130*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingTrackEventBasic(benchmark::State& state) {
131*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = StartTracing("track_event");
132*6dbdd20aSAndroid Build Coastguard Worker
133*6dbdd20aSAndroid Build Coastguard Worker while (state.KeepRunning()) {
134*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT_BEGIN("benchmark", "Event");
135*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
136*6dbdd20aSAndroid Build Coastguard Worker }
137*6dbdd20aSAndroid Build Coastguard Worker
138*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StopBlocking();
139*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(!tracing_session->ReadTraceBlocking().empty());
140*6dbdd20aSAndroid Build Coastguard Worker }
141*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingTrackEventDebugAnnotations(benchmark::State & state)142*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingTrackEventDebugAnnotations(benchmark::State& state) {
143*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = StartTracing("track_event");
144*6dbdd20aSAndroid Build Coastguard Worker
145*6dbdd20aSAndroid Build Coastguard Worker while (state.KeepRunning()) {
146*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT_BEGIN("benchmark", "Event", "value", 42);
147*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
148*6dbdd20aSAndroid Build Coastguard Worker }
149*6dbdd20aSAndroid Build Coastguard Worker
150*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StopBlocking();
151*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(!tracing_session->ReadTraceBlocking().empty());
152*6dbdd20aSAndroid Build Coastguard Worker }
153*6dbdd20aSAndroid Build Coastguard Worker
BM_TracingTrackEventLambda(benchmark::State & state)154*6dbdd20aSAndroid Build Coastguard Worker static void BM_TracingTrackEventLambda(benchmark::State& state) {
155*6dbdd20aSAndroid Build Coastguard Worker auto tracing_session = StartTracing("track_event");
156*6dbdd20aSAndroid Build Coastguard Worker
157*6dbdd20aSAndroid Build Coastguard Worker while (state.KeepRunning()) {
158*6dbdd20aSAndroid Build Coastguard Worker TRACE_EVENT_BEGIN("benchmark", "Event", [&](perfetto::EventContext ctx) {
159*6dbdd20aSAndroid Build Coastguard Worker auto* log = ctx.event()->set_log_message();
160*6dbdd20aSAndroid Build Coastguard Worker log->set_source_location_iid(42);
161*6dbdd20aSAndroid Build Coastguard Worker log->set_body_iid(1234);
162*6dbdd20aSAndroid Build Coastguard Worker });
163*6dbdd20aSAndroid Build Coastguard Worker benchmark::ClobberMemory();
164*6dbdd20aSAndroid Build Coastguard Worker }
165*6dbdd20aSAndroid Build Coastguard Worker
166*6dbdd20aSAndroid Build Coastguard Worker tracing_session->StopBlocking();
167*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(!tracing_session->ReadTraceBlocking().empty());
168*6dbdd20aSAndroid Build Coastguard Worker }
169*6dbdd20aSAndroid Build Coastguard Worker
170*6dbdd20aSAndroid Build Coastguard Worker } // namespace
171*6dbdd20aSAndroid Build Coastguard Worker
172*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingDataSourceDisabled);
173*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingDataSourceLambda);
174*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingDataSourceLambdaDifferentPacketSize)->Range(1, 1000);
175*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingTrackEventBasic);
176*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingTrackEventDebugAnnotations);
177*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingTrackEventDisabled);
178*6dbdd20aSAndroid Build Coastguard Worker BENCHMARK(BM_TracingTrackEventLambda);
179