Home | History | Annotate | Download | only in microbenchmarks
      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