From 3e04aade4e7a53aebbbed1a1268117f1f522bfb0 Mon Sep 17 00:00:00 2001 From: Greg Falcon Date: Wed, 18 May 2022 10:01:14 -0700 Subject: [PATCH] Replace direct uses of __builtin_prefetch from SwissTable with the wrapper functions. Add a new (internal) feature test macro to detect whether the wrappers are no-ops on a given platform. Note that one-arg __builtin_prefetch(x) is equivalent to __builtin_prefetch(x, 0, 3), per `man BUILTIN_PREFETCH(3)` and gcc docs. PiperOrigin-RevId: 449508660 Change-Id: I144e750205eec0c956d8dd62bc72e10bdb87c4f7 --- absl/base/internal/prefetch.h | 2 ++ absl/container/BUILD.bazel | 2 ++ absl/container/CMakeLists.txt | 2 ++ absl/container/internal/raw_hash_set.h | 14 +++++++------- absl/container/internal/raw_hash_set_test.cc | 1 + 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/absl/base/internal/prefetch.h b/absl/base/internal/prefetch.h index a71b3897..d4971a68 100644 --- a/absl/base/internal/prefetch.h +++ b/absl/base/internal/prefetch.h @@ -72,6 +72,8 @@ void PrefetchNta(const void* addr); #if ABSL_HAVE_BUILTIN(__builtin_prefetch) || defined(__GNUC__) +#define ABSL_INTERNAL_HAVE_PREFETCH 1 + // See __builtin_prefetch: // https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html. // diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index d733cb24..9ef7066c 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -589,6 +589,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:prefetch", "//absl/memory", "//absl/meta:type_traits", "//absl/numeric:bits", @@ -611,6 +612,7 @@ cc_test( "//absl/base", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:prefetch", "//absl/base:raw_logging_internal", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index aad69fa2..9b5c59a4 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -681,6 +681,7 @@ absl_cc_library( absl::memory absl::meta absl::optional + absl::prefetch absl::utility absl::hashtablez_sampler PUBLIC @@ -702,6 +703,7 @@ absl_cc_test( absl::base absl::config absl::core_headers + absl::prefetch absl::raw_logging_internal absl::strings GTest::gmock_main diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 56251b22..769af50f 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -197,6 +197,7 @@ #include "absl/base/config.h" #include "absl/base/internal/endian.h" +#include "absl/base/internal/prefetch.h" #include "absl/base/optimization.h" #include "absl/base/port.h" #include "absl/container/internal/common.h" @@ -1636,12 +1637,13 @@ class raw_hash_set { template void prefetch(const key_arg& key) const { (void)key; -#if defined(__GNUC__) + // Avoid probing if we won't be able to prefetch the addresses received. +#ifdef ABSL_INTERNAL_HAVE_PREFETCH prefetch_heap_block(); auto seq = probe(ctrl_, hash_ref()(key), capacity_); - __builtin_prefetch(static_cast(ctrl_ + seq.offset())); - __builtin_prefetch(static_cast(slots_ + seq.offset())); -#endif // __GNUC__ + base_internal::PrefetchT0(ctrl_ + seq.offset()); + base_internal::PrefetchT0(slots_ + seq.offset()); +#endif // ABSL_INTERNAL_HAVE_PREFETCH } // The API of find() has two extensions. @@ -2159,9 +2161,7 @@ class raw_hash_set { // This is intended to overlap with execution of calculating the hash for a // key. void prefetch_heap_block() const { -#if defined(__GNUC__) - __builtin_prefetch(static_cast(ctrl_), 0, 1); -#endif // __GNUC__ + base_internal::PrefetchT2(ctrl_); } HashtablezInfoHandle& infoz() { return settings_.template get<1>(); } diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 9cd88a28..914ec0c9 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -31,6 +31,7 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/cycleclock.h" +#include "absl/base/internal/prefetch.h" #include "absl/base/internal/raw_logging.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h"