• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2016 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 /* Benchmark gRPC end2end in various configurations */
20 
21 #ifndef TEST_CPP_MICROBENCHMARKS_FULLSTACK_STREAMING_PUMP_H
22 #define TEST_CPP_MICROBENCHMARKS_FULLSTACK_STREAMING_PUMP_H
23 
24 #include <benchmark/benchmark.h>
25 #include <sstream>
26 #include "src/core/lib/profiling/timers.h"
27 #include "src/proto/grpc/testing/echo.grpc.pb.h"
28 #include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
29 #include "test/cpp/microbenchmarks/fullstack_fixtures.h"
30 
31 namespace grpc {
32 namespace testing {
33 
34 /*******************************************************************************
35  * BENCHMARKING KERNELS
36  */
37 
tag(intptr_t x)38 static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); }
39 
40 template <class Fixture>
BM_PumpStreamClientToServer(benchmark::State & state)41 static void BM_PumpStreamClientToServer(benchmark::State& state) {
42   EchoTestService::AsyncService service;
43   std::unique_ptr<Fixture> fixture(new Fixture(&service));
44   {
45     EchoRequest send_request;
46     EchoRequest recv_request;
47     if (state.range(0) > 0) {
48       send_request.set_message(std::string(state.range(0), 'a'));
49     }
50     Status recv_status;
51     ServerContext svr_ctx;
52     ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
53     service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
54                               fixture->cq(), tag(0));
55     std::unique_ptr<EchoTestService::Stub> stub(
56         EchoTestService::NewStub(fixture->channel()));
57     ClientContext cli_ctx;
58     auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
59     int need_tags = (1 << 0) | (1 << 1);
60     void* t;
61     bool ok;
62     while (need_tags) {
63       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
64       GPR_ASSERT(ok);
65       int i = static_cast<int>((intptr_t)t);
66       GPR_ASSERT(need_tags & (1 << i));
67       need_tags &= ~(1 << i);
68     }
69     response_rw.Read(&recv_request, tag(0));
70     for (auto _ : state) {
71       GPR_TIMER_SCOPE("BenchmarkCycle", 0);
72       request_rw->Write(send_request, tag(1));
73       while (true) {
74         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
75         if (t == tag(0)) {
76           response_rw.Read(&recv_request, tag(0));
77         } else if (t == tag(1)) {
78           break;
79         } else {
80           GPR_ASSERT(false);
81         }
82       }
83     }
84     request_rw->WritesDone(tag(1));
85     need_tags = (1 << 0) | (1 << 1);
86     while (need_tags) {
87       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
88       int i = static_cast<int>((intptr_t)t);
89       GPR_ASSERT(need_tags & (1 << i));
90       need_tags &= ~(1 << i);
91     }
92     response_rw.Finish(Status::OK, tag(0));
93     Status final_status;
94     request_rw->Finish(&final_status, tag(1));
95     need_tags = (1 << 0) | (1 << 1);
96     while (need_tags) {
97       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
98       int i = static_cast<int>((intptr_t)t);
99       GPR_ASSERT(need_tags & (1 << i));
100       need_tags &= ~(1 << i);
101     }
102     GPR_ASSERT(final_status.ok());
103   }
104   fixture->Finish(state);
105   fixture.reset();
106   state.SetBytesProcessed(state.range(0) * state.iterations());
107 }
108 
109 template <class Fixture>
BM_PumpStreamServerToClient(benchmark::State & state)110 static void BM_PumpStreamServerToClient(benchmark::State& state) {
111   EchoTestService::AsyncService service;
112   std::unique_ptr<Fixture> fixture(new Fixture(&service));
113   {
114     EchoResponse send_response;
115     EchoResponse recv_response;
116     if (state.range(0) > 0) {
117       send_response.set_message(std::string(state.range(0), 'a'));
118     }
119     Status recv_status;
120     ServerContext svr_ctx;
121     ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
122     service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
123                               fixture->cq(), tag(0));
124     std::unique_ptr<EchoTestService::Stub> stub(
125         EchoTestService::NewStub(fixture->channel()));
126     ClientContext cli_ctx;
127     auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
128     int need_tags = (1 << 0) | (1 << 1);
129     void* t;
130     bool ok;
131     while (need_tags) {
132       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
133       GPR_ASSERT(ok);
134       int i = static_cast<int>((intptr_t)t);
135       GPR_ASSERT(need_tags & (1 << i));
136       need_tags &= ~(1 << i);
137     }
138     request_rw->Read(&recv_response, tag(0));
139     for (auto _ : state) {
140       GPR_TIMER_SCOPE("BenchmarkCycle", 0);
141       response_rw.Write(send_response, tag(1));
142       while (true) {
143         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
144         if (t == tag(0)) {
145           request_rw->Read(&recv_response, tag(0));
146         } else if (t == tag(1)) {
147           break;
148         } else {
149           GPR_ASSERT(false);
150         }
151       }
152     }
153     response_rw.Finish(Status::OK, tag(1));
154     need_tags = (1 << 0) | (1 << 1);
155     while (need_tags) {
156       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
157       int i = static_cast<int>((intptr_t)t);
158       GPR_ASSERT(need_tags & (1 << i));
159       need_tags &= ~(1 << i);
160     }
161   }
162   fixture->Finish(state);
163   fixture.reset();
164   state.SetBytesProcessed(state.range(0) * state.iterations());
165 }
166 }  // namespace testing
167 }  // namespace grpc
168 
169 #endif  // TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H
170