263314deb9317cda5a1f9feb3bee8b8bf07214ee
[platform/upstream/grpc.git] / test / cpp / microbenchmarks / bm_cq.cc
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 /* This benchmark exists to ensure that the benchmark integration is
20  * working */
21
22 #include <benchmark/benchmark.h>
23 #include <grpc/grpc.h>
24 #include <grpc/support/log.h>
25 #include <grpcpp/completion_queue.h>
26 #include <grpcpp/impl/grpc_library.h>
27 #include "test/cpp/microbenchmarks/helpers.h"
28 #include "test/cpp/util/test_config.h"
29
30 #include "src/core/lib/surface/completion_queue.h"
31
32 namespace grpc {
33 namespace testing {
34
35 static void BM_CreateDestroyCpp(benchmark::State& state) {
36   TrackCounters track_counters;
37   while (state.KeepRunning()) {
38     CompletionQueue cq;
39   }
40   track_counters.Finish(state);
41 }
42 BENCHMARK(BM_CreateDestroyCpp);
43
44 /* Create cq using a different constructor */
45 static void BM_CreateDestroyCpp2(benchmark::State& state) {
46   TrackCounters track_counters;
47   while (state.KeepRunning()) {
48     grpc_completion_queue* core_cq =
49         grpc_completion_queue_create_for_next(nullptr);
50     CompletionQueue cq(core_cq);
51   }
52   track_counters.Finish(state);
53 }
54 BENCHMARK(BM_CreateDestroyCpp2);
55
56 static void BM_CreateDestroyCore(benchmark::State& state) {
57   TrackCounters track_counters;
58   while (state.KeepRunning()) {
59     // TODO: sreek Templatize this benchmark and pass completion type and
60     // polling type as parameters
61     grpc_completion_queue_destroy(
62         grpc_completion_queue_create_for_next(nullptr));
63   }
64   track_counters.Finish(state);
65 }
66 BENCHMARK(BM_CreateDestroyCore);
67
68 static void DoneWithCompletionOnStack(void* arg,
69                                       grpc_cq_completion* completion) {}
70
71 class DummyTag final : public internal::CompletionQueueTag {
72  public:
73   bool FinalizeResult(void** tag, bool* status) override { return true; }
74 };
75
76 static void BM_Pass1Cpp(benchmark::State& state) {
77   TrackCounters track_counters;
78   CompletionQueue cq;
79   grpc_completion_queue* c_cq = cq.cq();
80   while (state.KeepRunning()) {
81     grpc_cq_completion completion;
82     DummyTag dummy_tag;
83     grpc_core::ExecCtx exec_ctx;
84     GPR_ASSERT(grpc_cq_begin_op(c_cq, &dummy_tag));
85     grpc_cq_end_op(c_cq, &dummy_tag, GRPC_ERROR_NONE, DoneWithCompletionOnStack,
86                    nullptr, &completion);
87
88     void* tag;
89     bool ok;
90     cq.Next(&tag, &ok);
91   }
92   track_counters.Finish(state);
93 }
94 BENCHMARK(BM_Pass1Cpp);
95
96 static void BM_Pass1Core(benchmark::State& state) {
97   TrackCounters track_counters;
98   // TODO: sreek Templatize this benchmark and pass polling_type as a param
99   grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
100   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
101   while (state.KeepRunning()) {
102     grpc_cq_completion completion;
103     grpc_core::ExecCtx exec_ctx;
104     GPR_ASSERT(grpc_cq_begin_op(cq, nullptr));
105     grpc_cq_end_op(cq, nullptr, GRPC_ERROR_NONE, DoneWithCompletionOnStack,
106                    nullptr, &completion);
107
108     grpc_completion_queue_next(cq, deadline, nullptr);
109   }
110   grpc_completion_queue_destroy(cq);
111   track_counters.Finish(state);
112 }
113 BENCHMARK(BM_Pass1Core);
114
115 static void BM_Pluck1Core(benchmark::State& state) {
116   TrackCounters track_counters;
117   // TODO: sreek Templatize this benchmark and pass polling_type as a param
118   grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr);
119   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
120   while (state.KeepRunning()) {
121     grpc_cq_completion completion;
122     grpc_core::ExecCtx exec_ctx;
123     GPR_ASSERT(grpc_cq_begin_op(cq, nullptr));
124     grpc_cq_end_op(cq, nullptr, GRPC_ERROR_NONE, DoneWithCompletionOnStack,
125                    nullptr, &completion);
126
127     grpc_completion_queue_pluck(cq, nullptr, deadline, nullptr);
128   }
129   grpc_completion_queue_destroy(cq);
130   track_counters.Finish(state);
131 }
132 BENCHMARK(BM_Pluck1Core);
133
134 static void BM_EmptyCore(benchmark::State& state) {
135   TrackCounters track_counters;
136   // TODO: sreek Templatize this benchmark and pass polling_type as a param
137   grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
138   gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
139   while (state.KeepRunning()) {
140     grpc_completion_queue_next(cq, deadline, nullptr);
141   }
142   grpc_completion_queue_destroy(cq);
143   track_counters.Finish(state);
144 }
145 BENCHMARK(BM_EmptyCore);
146
147 }  // namespace testing
148 }  // namespace grpc
149
150 // Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
151 // and others do not. This allows us to support both modes.
152 namespace benchmark {
153 void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
154 }  // namespace benchmark
155
156 int main(int argc, char** argv) {
157   LibraryInitializer libInit;
158   ::benchmark::Initialize(&argc, argv);
159   ::grpc::testing::InitTest(&argc, &argv, false);
160   benchmark::RunTheBenchmarksNamespaced();
161   return 0;
162 }