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 auto& force_library_initialization = Library::get(); 36 37 static void BM_CreateDestroyCpp(benchmark::State& state) { 38 TrackCounters track_counters; 39 while (state.KeepRunning()) { 40 CompletionQueue cq; 41 } 42 track_counters.Finish(state); 43 } 44 BENCHMARK(BM_CreateDestroyCpp); 45 46 /* Create cq using a different constructor */ 47 static void BM_CreateDestroyCpp2(benchmark::State& state) { 48 TrackCounters track_counters; 49 while (state.KeepRunning()) { 50 grpc_completion_queue* core_cq = 51 grpc_completion_queue_create_for_next(nullptr); 52 CompletionQueue cq(core_cq); 53 } 54 track_counters.Finish(state); 55 } 56 BENCHMARK(BM_CreateDestroyCpp2); 57 58 static void BM_CreateDestroyCore(benchmark::State& state) { 59 TrackCounters track_counters; 60 while (state.KeepRunning()) { 61 // TODO: sreek Templatize this benchmark and pass completion type and 62 // polling type as parameters 63 grpc_completion_queue_destroy( 64 grpc_completion_queue_create_for_next(nullptr)); 65 } 66 track_counters.Finish(state); 67 } 68 BENCHMARK(BM_CreateDestroyCore); 69 70 static void DoneWithCompletionOnStack(void* arg, 71 grpc_cq_completion* completion) {} 72 73 class DummyTag final : public internal::CompletionQueueTag { 74 public: 75 bool FinalizeResult(void** tag, bool* status) override { return true; } 76 }; 77 78 static void BM_Pass1Cpp(benchmark::State& state) { 79 TrackCounters track_counters; 80 CompletionQueue cq; 81 grpc_completion_queue* c_cq = cq.cq(); 82 while (state.KeepRunning()) { 83 grpc_cq_completion completion; 84 DummyTag dummy_tag; 85 grpc_core::ExecCtx exec_ctx; 86 GPR_ASSERT(grpc_cq_begin_op(c_cq, &dummy_tag)); 87 grpc_cq_end_op(c_cq, &dummy_tag, GRPC_ERROR_NONE, DoneWithCompletionOnStack, 88 nullptr, &completion); 89 90 void* tag; 91 bool ok; 92 cq.Next(&tag, &ok); 93 } 94 track_counters.Finish(state); 95 } 96 BENCHMARK(BM_Pass1Cpp); 97 98 static void BM_Pass1Core(benchmark::State& state) { 99 TrackCounters track_counters; 100 // TODO: sreek Templatize this benchmark and pass polling_type as a param 101 grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); 102 gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); 103 while (state.KeepRunning()) { 104 grpc_cq_completion completion; 105 grpc_core::ExecCtx exec_ctx; 106 GPR_ASSERT(grpc_cq_begin_op(cq, nullptr)); 107 grpc_cq_end_op(cq, nullptr, GRPC_ERROR_NONE, DoneWithCompletionOnStack, 108 nullptr, &completion); 109 110 grpc_completion_queue_next(cq, deadline, nullptr); 111 } 112 grpc_completion_queue_destroy(cq); 113 track_counters.Finish(state); 114 } 115 BENCHMARK(BM_Pass1Core); 116 117 static void BM_Pluck1Core(benchmark::State& state) { 118 TrackCounters track_counters; 119 // TODO: sreek Templatize this benchmark and pass polling_type as a param 120 grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr); 121 gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); 122 while (state.KeepRunning()) { 123 grpc_cq_completion completion; 124 grpc_core::ExecCtx exec_ctx; 125 GPR_ASSERT(grpc_cq_begin_op(cq, nullptr)); 126 grpc_cq_end_op(cq, nullptr, GRPC_ERROR_NONE, DoneWithCompletionOnStack, 127 nullptr, &completion); 128 129 grpc_completion_queue_pluck(cq, nullptr, deadline, nullptr); 130 } 131 grpc_completion_queue_destroy(cq); 132 track_counters.Finish(state); 133 } 134 BENCHMARK(BM_Pluck1Core); 135 136 static void BM_EmptyCore(benchmark::State& state) { 137 TrackCounters track_counters; 138 // TODO: sreek Templatize this benchmark and pass polling_type as a param 139 grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); 140 gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC); 141 while (state.KeepRunning()) { 142 grpc_completion_queue_next(cq, deadline, nullptr); 143 } 144 grpc_completion_queue_destroy(cq); 145 track_counters.Finish(state); 146 } 147 BENCHMARK(BM_EmptyCore); 148 149 } // namespace testing 150 } // namespace grpc 151 152 // Some distros have RunSpecifiedBenchmarks under the benchmark namespace, 153 // and others do not. This allows us to support both modes. 154 namespace benchmark { 155 void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } 156 } // namespace benchmark 157 158 int main(int argc, char** argv) { 159 ::benchmark::Initialize(&argc, argv); 160 ::grpc::testing::InitTest(&argc, &argv, false); 161 benchmark::RunTheBenchmarksNamespaced(); 162 return 0; 163 } 164