bm_pollset.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2017 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 /* Test out pollset latencies */
20 
21 #include <string.h>
22 
23 #include <benchmark/benchmark.h>
24 
25 #include <grpc/grpc.h>
26 #include <grpc/support/alloc.h>
27 #include <grpc/support/log.h>
28 
38 
39 #ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
40 #include <sys/epoll.h>
41 #include <sys/eventfd.h>
42 #include <unistd.h>
43 #endif
44 
45 static void shutdown_ps(void* ps, grpc_error_handle /*error*/) {
46  grpc_pollset_destroy(static_cast<grpc_pollset*>(ps));
47 }
48 
50  TrackCounters track_counters;
51  size_t ps_sz = grpc_pollset_size();
52  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_malloc(ps_sz));
53  gpr_mu* mu;
55  grpc_closure shutdown_ps_closure;
56  GRPC_CLOSURE_INIT(&shutdown_ps_closure, shutdown_ps, ps,
57  grpc_schedule_on_exec_ctx);
58  for (auto _ : state) {
59  memset(ps, 0, ps_sz);
60  grpc_pollset_init(ps, &mu);
61  gpr_mu_lock(mu);
62  grpc_pollset_shutdown(ps, &shutdown_ps_closure);
65  }
67  gpr_free(ps);
68  track_counters.Finish(state);
69 }
71 
72 #ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
73 static void BM_PollEmptyPollset_SpeedOfLight(benchmark::State& state) {
74  // equivalent to BM_PollEmptyPollset, but just use the OS primitives to guage
75  // what the speed of light would be if we abstracted perfectly
76  TrackCounters track_counters;
77  int epfd = epoll_create1(0);
78  GPR_ASSERT(epfd != -1);
79  size_t nev = state.range(0);
80  size_t nfd = state.range(1);
81  epoll_event* ev = new epoll_event[nev];
82  std::vector<int> fds;
83  for (size_t i = 0; i < nfd; i++) {
84  fds.push_back(eventfd(0, 0));
85  epoll_event ev;
86  ev.events = EPOLLIN;
87  epoll_ctl(epfd, EPOLL_CTL_ADD, fds.back(), &ev);
88  }
89  for (auto _ : state) {
90  epoll_wait(epfd, ev, nev, 0);
91  }
92  for (auto fd : fds) {
93  close(fd);
94  }
95  close(epfd);
96  delete[] ev;
97  track_counters.Finish(state);
98 }
99 BENCHMARK(BM_PollEmptyPollset_SpeedOfLight)
100  ->Args({1, 0})
101  ->Args({1, 1})
102  ->Args({1, 10})
103  ->Args({1, 100})
104  ->Args({1, 1000})
105  ->Args({1, 10000})
106  ->Args({1, 100000})
107  ->Args({10, 1})
108  ->Args({100, 1})
109  ->Args({1000, 1});
110 #endif
111 
113  TrackCounters track_counters;
114  size_t ps_sz = grpc_pollset_size();
115  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
116  gpr_mu* mu;
117  grpc_pollset_init(ps, &mu);
119  gpr_mu_lock(mu);
120  for (auto _ : state) {
123  }
124  grpc_closure shutdown_ps_closure;
125  GRPC_CLOSURE_INIT(&shutdown_ps_closure, shutdown_ps, ps,
126  grpc_schedule_on_exec_ctx);
127  grpc_pollset_shutdown(ps, &shutdown_ps_closure);
128  gpr_mu_unlock(mu);
130  gpr_free(ps);
131  track_counters.Finish(state);
132 }
134 
136  TrackCounters track_counters;
137  size_t ps_sz = grpc_pollset_size();
138  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
139  gpr_mu* mu;
140  grpc_pollset_init(ps, &mu);
142  grpc_wakeup_fd wakeup_fd;
143  GPR_ASSERT(
144  GRPC_LOG_IF_ERROR("wakeup_fd_init", grpc_wakeup_fd_init(&wakeup_fd)));
145  grpc_fd* fd = grpc_fd_create(wakeup_fd.read_fd, "xxx", false);
146  for (auto _ : state) {
147  grpc_pollset_add_fd(ps, fd);
149  }
150  grpc_fd_orphan(fd, nullptr, nullptr, "xxx");
151  grpc_closure shutdown_ps_closure;
152  GRPC_CLOSURE_INIT(&shutdown_ps_closure, shutdown_ps, ps,
153  grpc_schedule_on_exec_ctx);
154  gpr_mu_lock(mu);
155  grpc_pollset_shutdown(ps, &shutdown_ps_closure);
156  gpr_mu_unlock(mu);
158  gpr_free(ps);
159  track_counters.Finish(state);
160 }
162 
163 class TestClosure : public grpc_closure {
164  public:
165  virtual ~TestClosure() {}
166 };
167 
168 template <class F>
170  struct C : public TestClosure {
171  explicit C(F f) : f_(f) { GRPC_CLOSURE_INIT(this, C::cbfn, this, nullptr); }
172  static void cbfn(void* arg, grpc_error_handle /*error*/) {
173  C* p = static_cast<C*>(arg);
174  p->f_();
175  }
176  F f_;
177  };
178  return new C(f);
179 }
180 
181 #ifdef GRPC_LINUX_MULTIPOLL_WITH_EPOLL
182 static void BM_SingleThreadPollOneFd_SpeedOfLight(benchmark::State& state) {
183  // equivalent to BM_PollEmptyPollset, but just use the OS primitives to guage
184  // what the speed of light would be if we abstracted perfectly
185  TrackCounters track_counters;
186  int epfd = epoll_create1(0);
187  GPR_ASSERT(epfd != -1);
188  epoll_event ev[100];
189  int fd = eventfd(0, EFD_NONBLOCK);
190  ev[0].events = EPOLLIN;
191  epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev[0]);
192  for (auto _ : state) {
193  int err;
194  do {
195  err = eventfd_write(fd, 1);
196  } while (err < 0 && errno == EINTR);
197  GPR_ASSERT(err == 0);
198  do {
199  err = epoll_wait(epfd, ev, GPR_ARRAY_SIZE(ev), 0);
200  } while (err < 0 && errno == EINTR);
201  GPR_ASSERT(err == 1);
202  eventfd_t value;
203  do {
204  err = eventfd_read(fd, &value);
205  } while (err < 0 && errno == EINTR);
206  GPR_ASSERT(err == 0);
207  }
208  close(fd);
209  close(epfd);
210  track_counters.Finish(state);
211 }
212 BENCHMARK(BM_SingleThreadPollOneFd_SpeedOfLight);
213 #endif
214 
216  TrackCounters track_counters;
217  size_t ps_sz = grpc_pollset_size();
218  grpc_pollset* ps = static_cast<grpc_pollset*>(gpr_zalloc(ps_sz));
219  gpr_mu* mu;
220  grpc_pollset_init(ps, &mu);
222  grpc_wakeup_fd wakeup_fd;
224  grpc_fd* wakeup = grpc_fd_create(wakeup_fd.read_fd, "wakeup_read", false);
225  grpc_pollset_add_fd(ps, wakeup);
226  bool done = false;
227  TestClosure* continue_closure = MakeTestClosure([&]() {
229  if (!state.KeepRunning()) {
230  done = true;
231  return;
232  }
234  grpc_fd_notify_on_read(wakeup, continue_closure);
235  });
237  grpc_fd_notify_on_read(wakeup, continue_closure);
238  gpr_mu_lock(mu);
239  while (!done) {
242  }
243  grpc_fd_orphan(wakeup, nullptr, nullptr, "done");
244  wakeup_fd.read_fd = 0;
245  grpc_closure shutdown_ps_closure;
246  GRPC_CLOSURE_INIT(&shutdown_ps_closure, shutdown_ps, ps,
247  grpc_schedule_on_exec_ctx);
248  grpc_pollset_shutdown(ps, &shutdown_ps_closure);
249  gpr_mu_unlock(mu);
251  grpc_wakeup_fd_destroy(&wakeup_fd);
252  gpr_free(ps);
253  track_counters.Finish(state);
254  delete continue_closure;
255 }
257 
258 // Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
259 // and others do not. This allows us to support both modes.
260 namespace benchmark {
262 } // namespace benchmark
263 
264 int main(int argc, char** argv) {
265  grpc::testing::TestEnvironment env(&argc, argv);
266  LibraryInitializer libInit;
267  ::benchmark::Initialize(&argc, argv);
268  grpc::testing::InitTest(&argc, &argv, false);
270  return 0;
271 }
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
EPOLL_CTL_ADD
#define EPOLL_CTL_ADD
Definition: os390-syscalls.h:32
grpc::testing::InitTest
void InitTest(int *argc, char ***argv, bool remove_flags)
Definition: test_config_cc.cc:28
grpc_wakeup_fd_destroy
void grpc_wakeup_fd_destroy(grpc_wakeup_fd *fd_info)
grpc_wakeup_fd::read_fd
int read_fd
Definition: wakeup_fd_posix.h:75
grpc_pollset_size
size_t grpc_pollset_size(void)
Definition: pollset.cc:56
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
pollset.h
log.h
benchmark
Definition: bm_alarm.cc:55
generate.env
env
Definition: generate.py:37
memset
return memset(p, 0, total)
wakeup_fd_posix.h
grpc_wakeup_fd
Definition: wakeup_fd_posix.h:74
C
#define C(x)
Definition: abseil-cpp/absl/hash/internal/city_test.cc:49
string.h
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
useful.h
error_ref_leak.err
err
Definition: error_ref_leak.py:35
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
benchmark::RunTheBenchmarksNamespaced
void RunTheBenchmarksNamespaced()
Definition: bm_alarm.cc:56
BM_CreateDestroyPollset
static void BM_CreateDestroyPollset(benchmark::State &state)
Definition: bm_pollset.cc:49
grpc_pollset_work
grpc_error_handle grpc_pollset_work(grpc_pollset *pollset, grpc_pollset_worker **worker, grpc_core::Timestamp deadline)
Definition: pollset.cc:45
GRPC_LOG_IF_ERROR
#define GRPC_LOG_IF_ERROR(what, error)
Definition: error.h:398
BM_PollEmptyPollset
static void BM_PollEmptyPollset(benchmark::State &state)
Definition: bm_pollset.cc:112
xds_manager.p
p
Definition: xds_manager.py:60
TrackCounters::Finish
virtual void Finish(benchmark::State &state)
Definition: helpers.cc:44
MakeTestClosure
TestClosure * MakeTestClosure(F f)
Definition: bm_pollset.cc:169
shutdown_ps
static void shutdown_ps(void *ps, grpc_error_handle)
Definition: bm_pollset.cc:45
grpc_pollset_init
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu)
Definition: pollset.cc:33
BM_SingleThreadPollOneFd
static void BM_SingleThreadPollOneFd(benchmark::State &state)
Definition: bm_pollset.cc:215
epoll_create1
uv__os390_epoll * epoll_create1(int flags)
Definition: os390-syscalls.c:215
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
TrackCounters
Definition: helpers.h:51
benchmark::RunSpecifiedBenchmarks
size_t RunSpecifiedBenchmarks()
Definition: benchmark/src/benchmark.cc:437
TestClosure
Definition: bm_chttp2_transport.cc:166
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
hpack_encoder_fixtures::Args
Args({0, 16384})
grpc_wakeup_fd_wakeup
grpc_error_handle grpc_wakeup_fd_wakeup(grpc_wakeup_fd *fd_info) GRPC_MUST_USE_RESULT
ev_posix.h
grpc_core::ExecCtx::Flush
bool Flush()
Definition: exec_ctx.cc:69
grpc_fd
struct grpc_fd grpc_fd
Definition: ev_posix.h:44
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
grpc_wakeup_fd_init
grpc_error_handle grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) GRPC_MUST_USE_RESULT
grpc_fd_create
grpc_fd * grpc_fd_create(int fd, const char *name, bool track_err)
grpc.h
gmock_output_test._
_
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
grpc_wakeup_fd_consume_wakeup
grpc_error_handle grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd *fd_info) GRPC_MUST_USE_RESULT
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
arg
Definition: cmdline.cc:40
time.h
close
#define close
Definition: test-fs.c:48
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
BM_PollAddFd
static void BM_PollAddFd(benchmark::State &state)
Definition: bm_pollset.cc:135
benchmark::Initialize
void Initialize(int *argc, char **argv)
Definition: benchmark/src/benchmark.cc:602
epoll_wait
int epoll_wait(uv__os390_epoll *lst, struct epoll_event *events, int maxevents, int timeout)
Definition: os390-syscalls.c:284
helpers.h
grpc_core::Timestamp::ProcessEpoch
static constexpr Timestamp ProcessEpoch()
Definition: src/core/lib/gprpp/time.h:77
grpc_core::ExecCtx
Definition: exec_ctx.h:97
F
#define F(b, c, d)
Definition: md4.c:112
LibraryInitializer
Definition: helpers.h:33
test_config.h
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_fd_notify_on_read
void grpc_fd_notify_on_read(grpc_fd *fd, grpc_closure *closure)
main
int main(int argc, char **argv)
Definition: bm_pollset.cc:264
BENCHMARK
BENCHMARK(BM_CreateDestroyPollset)
GPR_ARRAY_SIZE
#define GPR_ARRAY_SIZE(array)
Definition: useful.h:129
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
port.h
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
epoll_event
Definition: os390-syscalls.h:40
grpc_pollset_shutdown
void grpc_pollset_shutdown(grpc_pollset *pollset, grpc_closure *closure)
Definition: pollset.cc:37
benchmark::State
Definition: benchmark/include/benchmark/benchmark.h:503
alloc.h
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
epoll_ctl
int epoll_ctl(uv__os390_epoll *lst, int op, int fd, struct epoll_event *event)
Definition: os390-syscalls.c:238
TestClosure::~TestClosure
virtual ~TestClosure()
Definition: bm_pollset.cc:165
grpc_pollset_add_fd
void grpc_pollset_add_fd(grpc_pollset *pollset, struct grpc_fd *fd)
arg
struct arg arg
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
test_config.h
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
grpc_fd_orphan
void grpc_fd_orphan(grpc_fd *fd, grpc_closure *on_done, int *release_fd, const char *reason)
epoll_event::events
int events
Definition: os390-syscalls.h:41
grpc_core::Timestamp::InfFuture
static constexpr Timestamp InfFuture()
Definition: src/core/lib/gprpp/time.h:79
grpc_error
Definition: error_internal.h:42
grpc_pollset
Definition: bm_cq_multiple_threads.cc:37
grpc_pollset_destroy
void grpc_pollset_destroy(grpc_pollset *pollset)
Definition: pollset.cc:41
grpc_closure
Definition: closure.h:56
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:49