summaryrefslogtreecommitdiff
path: root/absl/hash
diff options
context:
space:
mode:
authorGravatar Connal de Souza <connaldesouza@google.com>2024-03-28 10:21:43 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2024-03-28 10:22:38 -0700
commitc0f104bf3aca7001d8a549f5efe15f89ee99d050 (patch)
tree3e5524d4b6d7917787f0b29fb9e1cf4dea72b955 /absl/hash
parentc5d722bc4eb4d833212f2cb5335e6ace569e5fbc (diff)
Optimize LowLevelHash by breaking dependency between final loads and previous len/ptr updates.
No functional change. PiperOrigin-RevId: 619979819 Change-Id: I71a4ae14272bcdf1da2e201ed286f95213ecb5e2
Diffstat (limited to 'absl/hash')
-rw-r--r--absl/hash/internal/low_level_hash.cc8
1 files changed, 3 insertions, 5 deletions
diff --git a/absl/hash/internal/low_level_hash.cc b/absl/hash/internal/low_level_hash.cc
index 43de6729..6dc71cf7 100644
--- a/absl/hash/internal/low_level_hash.cc
+++ b/absl/hash/internal/low_level_hash.cc
@@ -37,6 +37,7 @@ uint64_t LowLevelHashLenGt16(const void* data, size_t len, uint64_t seed,
PrefetchToLocalCache(data);
const uint8_t* ptr = static_cast<const uint8_t*>(data);
uint64_t starting_length = static_cast<uint64_t>(len);
+ const uint8_t* last_16_ptr = ptr + starting_length - 16;
uint64_t current_state = seed ^ salt[0];
if (len > 64) {
@@ -97,15 +98,12 @@ uint64_t LowLevelHashLenGt16(const void* data, size_t len, uint64_t seed,
uint64_t b = absl::base_internal::UnalignedLoad64(ptr + 8);
current_state = Mix(a ^ salt[1], b ^ current_state);
-
- ptr += 16;
- len -= 16;
}
// We now have a data `ptr` with at least 1 and at most 16 bytes. But we can
// safely read from `ptr + len - 16`.
- uint64_t a = absl::base_internal::UnalignedLoad64(ptr + len - 16);
- uint64_t b = absl::base_internal::UnalignedLoad64(ptr + len - 8);
+ uint64_t a = absl::base_internal::UnalignedLoad64(last_16_ptr);
+ uint64_t b = absl::base_internal::UnalignedLoad64(last_16_ptr + 8);
return Mix(a ^ salt[1] ^ starting_length, b ^ current_state);
}