From cdb723815b66e3bac2c9ca87dc9f8322488a6bc9 Mon Sep 17 00:00:00 2001 From: Nelson Liang Date: Tue, 23 Jul 2024 13:56:00 -0700 Subject: [PATCH] Add Prefetchers to Proto Copy Construct to help address load misses PiperOrigin-RevId: 655292932 --- src/google/protobuf/arena.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index a3cd7b7654bf..4ec1eaba9622 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -29,6 +29,8 @@ using type_info = ::type_info; #include "absl/base/attributes.h" #include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/base/prefetch.h" #include "absl/log/absl_check.h" #include "absl/utility/internal/if_constexpr.h" #include "google/protobuf/arena_align.h" @@ -665,6 +667,12 @@ PROTOBUF_NOINLINE void* Arena::DefaultConstruct(Arena* arena) { template PROTOBUF_NOINLINE void* Arena::CopyConstruct(Arena* arena, const void* from) { + // If the object is larger than half a cache line, prefetch it. + // This way of prefetching is a little more aggressive than if we + // condition off a whole cache line, but benchmarks show better results. + if (sizeof(T) > ABSL_CACHELINE_SIZE / 2) { + PROTOBUF_PREFETCH_WITH_OFFSET(from, 64); + } static_assert(is_destructor_skippable::value, ""); void* mem = arena != nullptr ? arena->AllocateAligned(sizeof(T)) : ::operator new(sizeof(T));