Merge pull request #9693 from ctiller/bm_closure

Add benchmarks of closures, combiners, exec_ctx primitives
pull/9708/head
Craig Tiller 8 years ago committed by GitHub
commit 2e0f02b5fb
  1. 39
      CMakeLists.txt
  2. 48
      Makefile
  3. 17
      build.yaml
  4. 356
      test/cpp/microbenchmarks/bm_closure.cc
  5. 10
      tools/profiling/microbenchmarks/bm2bq.py
  6. 18
      tools/run_tests/generated/sources_and_headers.json
  7. 22
      tools/run_tests/generated/tests.json
  8. 2
      tools/run_tests/run_microbenchmark.py

@ -570,6 +570,9 @@ add_dependencies(buildtests_cxx alarm_cpp_test)
add_dependencies(buildtests_cxx async_end2end_test) add_dependencies(buildtests_cxx async_end2end_test)
add_dependencies(buildtests_cxx auth_property_iterator_test) add_dependencies(buildtests_cxx auth_property_iterator_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_closure)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_fullstack) add_dependencies(buildtests_cxx bm_fullstack)
endif() endif()
add_dependencies(buildtests_cxx channel_arguments_test) add_dependencies(buildtests_cxx channel_arguments_test)
@ -7447,6 +7450,42 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_closure
test/cpp/microbenchmarks/bm_closure.cc
third_party/googletest/src/gtest-all.cc
)
target_include_directories(bm_closure
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
PRIVATE third_party/googletest/include
PRIVATE third_party/googletest
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(bm_closure
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
benchmark
grpc_test_util
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(bm_fullstack add_executable(bm_fullstack
test/cpp/microbenchmarks/bm_fullstack.cc test/cpp/microbenchmarks/bm_fullstack.cc
third_party/googletest/src/gtest-all.cc third_party/googletest/src/gtest-all.cc

@ -1043,6 +1043,7 @@ wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test
alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test
async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
bm_closure: $(BINDIR)/$(CONFIG)/bm_closure
bm_fullstack: $(BINDIR)/$(CONFIG)/bm_fullstack bm_fullstack: $(BINDIR)/$(CONFIG)/bm_fullstack
channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test
@ -1449,6 +1450,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \ $(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \ $(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/bm_closure \
$(BINDIR)/$(CONFIG)/bm_fullstack \ $(BINDIR)/$(CONFIG)/bm_fullstack \
$(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/channel_filter_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \
@ -1553,6 +1555,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \ $(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \ $(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/bm_closure \
$(BINDIR)/$(CONFIG)/bm_fullstack \ $(BINDIR)/$(CONFIG)/bm_fullstack \
$(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/channel_filter_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \
@ -1870,6 +1873,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing auth_property_iterator_test" $(E) "[RUN] Testing auth_property_iterator_test"
$(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 )
$(E) "[RUN] Testing bm_closure"
$(Q) $(BINDIR)/$(CONFIG)/bm_closure || ( echo test bm_closure failed ; exit 1 )
$(E) "[RUN] Testing bm_fullstack" $(E) "[RUN] Testing bm_fullstack"
$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack || ( echo test bm_fullstack failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack || ( echo test bm_fullstack failed ; exit 1 )
$(E) "[RUN] Testing channel_arguments_test" $(E) "[RUN] Testing channel_arguments_test"
@ -12391,6 +12396,49 @@ endif
endif endif
BM_CLOSURE_SRC = \
test/cpp/microbenchmarks/bm_closure.cc \
BM_CLOSURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CLOSURE_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_closure: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/bm_closure: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_closure: $(PROTOBUF_DEP) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_CLOSURE_OBJS) $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_closure
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_closure.o: $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_CLOSURE_OBJS:.o=.dep)
endif
endif
BM_FULLSTACK_SRC = \ BM_FULLSTACK_SRC = \
test/cpp/microbenchmarks/bm_fullstack.cc \ test/cpp/microbenchmarks/bm_fullstack.cc \

@ -2987,6 +2987,23 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
- name: bm_closure
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_closure.cc
deps:
- benchmark
- grpc_test_util
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
platforms:
- mac
- linux
- posix
- name: bm_fullstack - name: bm_fullstack
build: test build: test
language: c++ language: c++

@ -0,0 +1,356 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* Test various closure related operations */
#include <grpc/grpc.h>
extern "C" {
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/exec_ctx.h"
}
#include "third_party/benchmark/include/benchmark/benchmark.h"
static class InitializeStuff {
public:
InitializeStuff() { grpc_init(); }
~InitializeStuff() { grpc_shutdown(); }
} initialize_stuff;
static void BM_NoOpExecCtx(benchmark::State& state) {
while (state.KeepRunning()) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_exec_ctx_finish(&exec_ctx);
}
}
BENCHMARK(BM_NoOpExecCtx);
static void BM_WellFlushed(benchmark::State& state) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_exec_ctx_flush(&exec_ctx);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_WellFlushed);
static void DoNothing(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {}
static void BM_ClosureInitAgainstExecCtx(benchmark::State& state) {
grpc_closure c;
while (state.KeepRunning()) {
benchmark::DoNotOptimize(
grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx));
}
}
BENCHMARK(BM_ClosureInitAgainstExecCtx);
static void BM_ClosureInitAgainstCombiner(benchmark::State& state) {
grpc_combiner* combiner = grpc_combiner_create(NULL);
grpc_closure c;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
benchmark::DoNotOptimize(grpc_closure_init(
&c, DoNothing, NULL, grpc_combiner_scheduler(combiner, false)));
}
GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureInitAgainstCombiner);
static void BM_ClosureRunOnExecCtx(benchmark::State& state) {
grpc_closure c;
grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_run(&exec_ctx, &c, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureRunOnExecCtx);
static void BM_ClosureCreateAndRun(benchmark::State& state) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_run(&exec_ctx, grpc_closure_create(DoNothing, NULL,
grpc_schedule_on_exec_ctx),
GRPC_ERROR_NONE);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureCreateAndRun);
static void BM_ClosureInitAndRun(benchmark::State& state) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_closure c;
while (state.KeepRunning()) {
grpc_closure_run(&exec_ctx, grpc_closure_init(&c, DoNothing, NULL,
grpc_schedule_on_exec_ctx),
GRPC_ERROR_NONE);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureInitAndRun);
static void BM_ClosureSchedOnExecCtx(benchmark::State& state) {
grpc_closure c;
grpc_closure_init(&c, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSchedOnExecCtx);
static void BM_ClosureSched2OnExecCtx(benchmark::State& state) {
grpc_closure c1;
grpc_closure c2;
grpc_closure_init(&c1, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_closure_init(&c2, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c1, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c2, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSched2OnExecCtx);
static void BM_ClosureSched3OnExecCtx(benchmark::State& state) {
grpc_closure c1;
grpc_closure c2;
grpc_closure c3;
grpc_closure_init(&c1, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_closure_init(&c2, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_closure_init(&c3, DoNothing, NULL, grpc_schedule_on_exec_ctx);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c1, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c2, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c3, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSched3OnExecCtx);
static void BM_AcquireMutex(benchmark::State& state) {
// for comparison with the combiner stuff below
gpr_mu mu;
gpr_mu_init(&mu);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
gpr_mu_lock(&mu);
DoNothing(&exec_ctx, NULL, GRPC_ERROR_NONE);
gpr_mu_unlock(&mu);
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_AcquireMutex);
static void BM_ClosureSchedOnCombiner(benchmark::State& state) {
grpc_combiner* combiner = grpc_combiner_create(NULL);
grpc_closure c;
grpc_closure_init(&c, DoNothing, NULL,
grpc_combiner_scheduler(combiner, false));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSchedOnCombiner);
static void BM_ClosureSched2OnCombiner(benchmark::State& state) {
grpc_combiner* combiner = grpc_combiner_create(NULL);
grpc_closure c1;
grpc_closure c2;
grpc_closure_init(&c1, DoNothing, NULL,
grpc_combiner_scheduler(combiner, false));
grpc_closure_init(&c2, DoNothing, NULL,
grpc_combiner_scheduler(combiner, false));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c1, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c2, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSched2OnCombiner);
static void BM_ClosureSched3OnCombiner(benchmark::State& state) {
grpc_combiner* combiner = grpc_combiner_create(NULL);
grpc_closure c1;
grpc_closure c2;
grpc_closure c3;
grpc_closure_init(&c1, DoNothing, NULL,
grpc_combiner_scheduler(combiner, false));
grpc_closure_init(&c2, DoNothing, NULL,
grpc_combiner_scheduler(combiner, false));
grpc_closure_init(&c3, DoNothing, NULL,
grpc_combiner_scheduler(combiner, false));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c1, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c2, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c3, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSched3OnCombiner);
static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) {
grpc_combiner* combiner1 = grpc_combiner_create(NULL);
grpc_combiner* combiner2 = grpc_combiner_create(NULL);
grpc_closure c1;
grpc_closure c2;
grpc_closure_init(&c1, DoNothing, NULL,
grpc_combiner_scheduler(combiner1, false));
grpc_closure_init(&c2, DoNothing, NULL,
grpc_combiner_scheduler(combiner2, false));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c1, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c2, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
GRPC_COMBINER_UNREF(&exec_ctx, combiner1, "finished");
GRPC_COMBINER_UNREF(&exec_ctx, combiner2, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSched2OnTwoCombiners);
static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) {
grpc_combiner* combiner1 = grpc_combiner_create(NULL);
grpc_combiner* combiner2 = grpc_combiner_create(NULL);
grpc_closure c1;
grpc_closure c2;
grpc_closure c3;
grpc_closure c4;
grpc_closure_init(&c1, DoNothing, NULL,
grpc_combiner_scheduler(combiner1, false));
grpc_closure_init(&c2, DoNothing, NULL,
grpc_combiner_scheduler(combiner2, false));
grpc_closure_init(&c3, DoNothing, NULL,
grpc_combiner_scheduler(combiner1, false));
grpc_closure_init(&c4, DoNothing, NULL,
grpc_combiner_scheduler(combiner2, false));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_closure_sched(&exec_ctx, &c1, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c2, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c3, GRPC_ERROR_NONE);
grpc_closure_sched(&exec_ctx, &c4, GRPC_ERROR_NONE);
grpc_exec_ctx_flush(&exec_ctx);
}
GRPC_COMBINER_UNREF(&exec_ctx, combiner1, "finished");
GRPC_COMBINER_UNREF(&exec_ctx, combiner2, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureSched4OnTwoCombiners);
// Helper that continuously reschedules the same closure against something until
// the benchmark is complete
class Rescheduler {
public:
Rescheduler(benchmark::State& state, grpc_closure_scheduler* scheduler)
: state_(state) {
grpc_closure_init(&closure_, Step, this, scheduler);
}
void ScheduleFirst(grpc_exec_ctx* exec_ctx) {
grpc_closure_sched(exec_ctx, &closure_, GRPC_ERROR_NONE);
}
void ScheduleFirstAgainstDifferentScheduler(
grpc_exec_ctx* exec_ctx, grpc_closure_scheduler* scheduler) {
grpc_closure_sched(exec_ctx, grpc_closure_create(Step, this, scheduler),
GRPC_ERROR_NONE);
}
private:
benchmark::State& state_;
grpc_closure closure_;
static void Step(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
Rescheduler* self = static_cast<Rescheduler*>(arg);
if (self->state_.KeepRunning()) {
grpc_closure_sched(exec_ctx, &self->closure_, GRPC_ERROR_NONE);
}
}
};
static void BM_ClosureReschedOnExecCtx(benchmark::State& state) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Rescheduler r(state, grpc_schedule_on_exec_ctx);
r.ScheduleFirst(&exec_ctx);
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureReschedOnExecCtx);
static void BM_ClosureReschedOnCombiner(benchmark::State& state) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_combiner* combiner = grpc_combiner_create(NULL);
Rescheduler r(state, grpc_combiner_scheduler(combiner, false));
r.ScheduleFirst(&exec_ctx);
grpc_exec_ctx_flush(&exec_ctx);
GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureReschedOnCombiner);
static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_combiner* combiner = grpc_combiner_create(NULL);
Rescheduler r(state, grpc_combiner_finally_scheduler(combiner, false));
r.ScheduleFirstAgainstDifferentScheduler(
&exec_ctx, grpc_combiner_scheduler(combiner, false));
grpc_exec_ctx_flush(&exec_ctx);
GRPC_COMBINER_UNREF(&exec_ctx, combiner, "finished");
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_ClosureReschedOnCombinerFinally);
BENCHMARK_MAIN();

@ -115,6 +115,8 @@ def numericalize(s):
assert 'not a number: %s' % s assert 'not a number: %s' % s
def parse_name(name): def parse_name(name):
if '<' not in name and '/' not in name and name not in bm_specs:
return {'name': name}
rest = name rest = name
out = {} out = {}
tpl_args = [] tpl_args = []
@ -145,7 +147,7 @@ def parse_name(name):
rest = s[0] rest = s[0]
dyn_args = s[1:] dyn_args = s[1:]
name = rest name = rest
assert name in bm_specs assert name in bm_specs, 'bm_specs needs to be expanded for %s' % name
assert len(dyn_args) == len(bm_specs[name]['dyn']) assert len(dyn_args) == len(bm_specs[name]['dyn'])
assert len(tpl_args) == len(bm_specs[name]['tpl']) assert len(tpl_args) == len(bm_specs[name]['tpl'])
out['name'] = name out['name'] = name
@ -155,10 +157,13 @@ def parse_name(name):
for bm in js['benchmarks']: for bm in js['benchmarks']:
context = js['context'] context = js['context']
labels_list = [s.split(':') for s in bm.get('label', '').split(' ')] if 'label' in bm:
labels_list = [s.split(':') for s in bm['label'].split(' ')]
for el in labels_list: for el in labels_list:
el[0] = el[0].replace('/iter', '_per_iteration') el[0] = el[0].replace('/iter', '_per_iteration')
labels = dict(labels_list) labels = dict(labels_list)
else:
labels = {}
row = { row = {
'jenkins_build': os.environ.get('BUILD_NUMBER', ''), 'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
'jenkins_job': os.environ.get('JOB_NAME', ''), 'jenkins_job': os.environ.get('JOB_NAME', ''),
@ -167,5 +172,6 @@ for bm in js['benchmarks']:
row.update(bm) row.update(bm)
row.update(parse_name(row['name'])) row.update(parse_name(row['name']))
row.update(labels) row.update(labels)
if 'label' in row:
del row['label'] del row['label']
writer.writerow(row) writer.writerow(row)

@ -2363,6 +2363,24 @@
"third_party": false, "third_party": false,
"type": "target" "type": "target"
}, },
{
"deps": [
"benchmark",
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c++",
"name": "bm_closure",
"src": [
"test/cpp/microbenchmarks/bm_closure.cc"
],
"third_party": false,
"type": "target"
},
{ {
"deps": [ "deps": [
"benchmark", "benchmark",

@ -2469,6 +2469,28 @@
"windows" "windows"
] ]
}, },
{
"args": [
"--benchmark_min_time=0"
],
"ci_platforms": [
"linux",
"mac",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c++",
"name": "bm_closure",
"platforms": [
"linux",
"mac",
"posix"
]
},
{ {
"args": [ "args": [
"--benchmark_min_time=0" "--benchmark_min_time=0"

@ -195,7 +195,7 @@ argp.add_argument('-c', '--collect',
default=sorted(collectors.keys()), default=sorted(collectors.keys()),
help='Which collectors should be run against each benchmark') help='Which collectors should be run against each benchmark')
argp.add_argument('-b', '--benchmarks', argp.add_argument('-b', '--benchmarks',
default=['bm_fullstack'], default=['bm_fullstack', 'bm_closure'],
nargs='+', nargs='+',
type=str, type=str,
help='Which microbenchmarks should be run') help='Which microbenchmarks should be run')

Loading…
Cancel
Save