aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp/microbenchmarks
diff options
context:
space:
mode:
authorGravatar hcaseyal <hcaseyal@gmail.com>2018-09-20 14:56:50 -0700
committerGravatar GitHub <noreply@github.com>2018-09-20 14:56:50 -0700
commit07308653a8ed2ec0ff7ef3a35197bf5b6caaee8b (patch)
treef3abbaa18609ecb7f9965d995ac482a923925d25 /test/cpp/microbenchmarks
parent0dd651dcea7fc99007e3282d15ea990e97f335c2 (diff)
parent4c6e7ce15dea5cdb51ef2021aa539d16cbd30991 (diff)
Merge pull request #16629 from hcaseyal/fix_hpack_microbenchmarks
Add benchmarks for on_initial_header
Diffstat (limited to 'test/cpp/microbenchmarks')
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_hpack.cc74
1 files changed, 69 insertions, 5 deletions
diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
index 6fcf048bf3..ba4b57ad22 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
@@ -27,6 +27,7 @@
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -456,8 +457,9 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
std::vector<grpc_slice> benchmark_slices = Fixture::GetBenchmarkSlices();
grpc_chttp2_hpack_parser p;
grpc_chttp2_hpack_parser_init(&p);
+ const int kArenaSize = 4096 * 4096;
+ p.on_header_user_data = gpr_arena_create(kArenaSize);
p.on_header = OnHeader;
- p.on_header_user_data = nullptr;
for (auto slice : init_slices) {
GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice));
}
@@ -466,7 +468,14 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice));
}
grpc_core::ExecCtx::Get()->Flush();
+ // Recreate arena every 4k iterations to avoid oom
+ if (0 == (state.iterations() & 0xfff)) {
+ gpr_arena_destroy((gpr_arena*)p.on_header_user_data);
+ p.on_header_user_data = gpr_arena_create(kArenaSize);
+ }
}
+ // Clean up
+ gpr_arena_destroy((gpr_arena*)p.on_header_user_data);
for (auto slice : init_slices) grpc_slice_unref(slice);
for (auto slice : benchmark_slices) grpc_slice_unref(slice);
grpc_chttp2_hpack_parser_destroy(&p);
@@ -766,8 +775,58 @@ class RepresentativeServerTrailingMetadata {
static void free_timeout(void* p) { gpr_free(p); }
-// New implementation.
-static void OnHeaderNew(void* user_data, grpc_mdelem md) {
+// Benchmark the current on_initial_header implementation
+static void OnInitialHeader(void* user_data, grpc_mdelem md) {
+ // Setup for benchmark. This will bloat the absolute values of this benchmark
+ grpc_chttp2_incoming_metadata_buffer buffer;
+ grpc_chttp2_incoming_metadata_buffer_init(&buffer, (gpr_arena*)user_data);
+ bool seen_error = false;
+
+ // Below here is the code we actually care about benchmarking
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
+ seen_error = true;
+ }
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
+ grpc_millis* cached_timeout =
+ static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
+ grpc_millis timeout;
+ if (cached_timeout != nullptr) {
+ timeout = *cached_timeout;
+ } else {
+ if (GPR_UNLIKELY(
+ !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
+ char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
+ gpr_free(val);
+ timeout = GRPC_MILLIS_INF_FUTURE;
+ }
+ if (GRPC_MDELEM_IS_INTERNED(md)) {
+ /* not already parsed: parse it now, and store the
+ * result away */
+ cached_timeout =
+ static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
+ *cached_timeout = timeout;
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ }
+ }
+ benchmark::DoNotOptimize(timeout);
+ GRPC_MDELEM_UNREF(md);
+ } else {
+ const size_t new_size = buffer.size + GRPC_MDELEM_LENGTH(md);
+ if (!seen_error) {
+ buffer.size = new_size;
+ }
+ grpc_error* error = grpc_chttp2_incoming_metadata_buffer_add(&buffer, md);
+ if (error != GRPC_ERROR_NONE) {
+ GPR_ASSERT(0);
+ }
+ }
+ grpc_chttp2_incoming_metadata_buffer_destroy(&buffer);
+}
+
+// Benchmark timeout handling
+static void OnHeaderTimeout(void* user_data, grpc_mdelem md) {
if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
grpc_millis* cached_timeout =
static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
@@ -853,8 +912,13 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeServerInitialMetadata, UnrefHeader);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeServerTrailingMetadata, UnrefHeader);
-
-BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderNew);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
+ RepresentativeClientInitialMetadata, OnInitialHeader);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
+ MoreRepresentativeClientInitialMetadata, OnInitialHeader);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
+ RepresentativeServerInitialMetadata, OnInitialHeader);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderTimeout);
} // namespace hpack_parser_fixtures