summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-12-14 21:51:13 -0800
committerGravatar Mark Barolak <mbar@google.com>2020-12-15 10:08:56 -0500
commit68f1ad93251744f096036e65241493774b4e7ac0 (patch)
tree82fc5e49db344026ea67cffea1c30f3ac73ed6f6
parent52acfe6fc6b8bb9b1b7854993dd0fb33f0f3c4af (diff)
Export of internal Abseil changes
-- f0456157cdc6cef6dbb5d2f99f9dc3ca0e213fab by Abseil Team <absl-team@google.com>: Improve flag_benchmark reproducibility, test multiple threads This adds multiple threads to the flags benchmark, and also uses some linker magic to ensure that the defined flags are mapped to a consistent alignment regardless of other code changes in the benchmark binary. The benchmark performance in multiple threads is somewhat sensitive to the alignment of the FlagImpl class, depending on whether the flag value and the absl::Mutex are on the same cacheline or different ones. Making all flags be cacheline-aligned would probably waste too much memory, so this CL instead just makes the memory alignment consistent within the tests. PiperOrigin-RevId: 347536882 -- a019646d306b9497a1eba7efa5e2c4c651d9979d by Derek Mauro <dmauro@google.com>: Fix other comments in node_hash_set.h PiperOrigin-RevId: 347462975 -- 66a4b39fe84a3e81935ad08ee76291df13d1d5e6 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 347436244 -- 52f4d18c2c4439d26428f64ac4de41e6183919ee by Mark Barolak <mbar@google.com>: container: fix introduction for node_hash_set.h Import of https://github.com/abseil/abseil-cpp/pull/861 PiperOrigin-RevId: 347432772 GitOrigin-RevId: f0456157cdc6cef6dbb5d2f99f9dc3ca0e213fab Change-Id: I629f27e5b9584d92b0a42284c1acf708779bad3f
-rw-r--r--absl/container/node_hash_set.h30
-rw-r--r--absl/flags/BUILD.bazel4
-rw-r--r--absl/flags/flag_benchmark.cc13
-rw-r--r--absl/flags/flag_benchmark.lds13
-rw-r--r--absl/strings/cord.cc1
5 files changed, 44 insertions, 17 deletions
diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h
index 56ce3b66..93b15f46 100644
--- a/absl/container/node_hash_set.h
+++ b/absl/container/node_hash_set.h
@@ -18,7 +18,7 @@
//
// An `absl::node_hash_set<T>` is an unordered associative container designed to
// be a more efficient replacement for `std::unordered_set`. Like
-// `unordered_set`, search, insertion, and deletion of map elements can be done
+// `unordered_set`, search, insertion, and deletion of set elements can be done
// as an `O(1)` operation. However, `node_hash_set` (and other unordered
// associative containers known as the collection of Abseil "Swiss tables")
// contain other optimizations that result in both memory and computation
@@ -60,7 +60,7 @@ struct NodeHashSetPolicy;
// following notable differences:
//
// * Supports heterogeneous lookup, through `find()`, `operator[]()` and
-// `insert()`, provided that the map is provided a compatible heterogeneous
+// `insert()`, provided that the set is provided a compatible heterogeneous
// hashing function and equality operator.
// * Contains a `capacity()` member function indicating the number of element
// slots (open, deleted, and empty) within the hash set.
@@ -76,13 +76,13 @@ struct NodeHashSetPolicy;
// Example:
//
// // Create a node hash set of three strings
-// absl::node_hash_map<std::string, std::string> ducks =
+// absl::node_hash_set<std::string> ducks =
// {"huey", "dewey", "louie"};
//
-// // Insert a new element into the node hash map
-// ducks.insert("donald"};
+// // Insert a new element into the node hash set
+// ducks.insert("donald");
//
-// // Force a rehash of the node hash map
+// // Force a rehash of the node hash set
// ducks.rehash(0);
//
// // See if "dewey" is present
@@ -100,7 +100,7 @@ class node_hash_set
public:
// Constructors and Assignment Operators
//
- // A node_hash_set supports the same overload set as `std::unordered_map`
+ // A node_hash_set supports the same overload set as `std::unordered_set`
// for construction and assignment:
//
// * Default constructor
@@ -167,7 +167,7 @@ class node_hash_set
// available within the `node_hash_set`.
//
// NOTE: this member function is particular to `absl::node_hash_set` and is
- // not provided in the `std::unordered_map` API.
+ // not provided in the `std::unordered_set` API.
using Base::capacity;
// node_hash_set::empty()
@@ -208,7 +208,7 @@ class node_hash_set
// `void`.
//
// NOTE: this return behavior is different than that of STL containers in
- // general and `std::unordered_map` in particular.
+ // general and `std::unordered_set` in particular.
//
// iterator erase(const_iterator first, const_iterator last):
//
@@ -314,7 +314,7 @@ class node_hash_set
// node_hash_set::merge()
//
- // Extracts elements from a given `source` flat hash map into this
+ // Extracts elements from a given `source` node hash set into this
// `node_hash_set`. If the destination `node_hash_set` already contains an
// element with an equivalent key, that element is not extracted.
using Base::merge;
@@ -322,15 +322,15 @@ class node_hash_set
// node_hash_set::swap(node_hash_set& other)
//
// Exchanges the contents of this `node_hash_set` with those of the `other`
- // flat hash map, avoiding invocation of any move, copy, or swap operations on
+ // node hash set, avoiding invocation of any move, copy, or swap operations on
// individual elements.
//
// All iterators and references on the `node_hash_set` remain valid, excepting
// for the past-the-end iterator, which is invalidated.
//
- // `swap()` requires that the flat hash set's hashing and key equivalence
+ // `swap()` requires that the node hash set's hashing and key equivalence
// functions be Swappable, and are exchaged using unqualified calls to
- // non-member `swap()`. If the map's allocator has
+ // non-member `swap()`. If the set's allocator has
// `std::allocator_traits<allocator_type>::propagate_on_container_swap::value`
// set to `true`, the allocators are also exchanged using an unqualified call
// to non-member `swap()`; otherwise, the allocators are not swapped.
@@ -385,14 +385,14 @@ class node_hash_set
// node_hash_set::bucket_count()
//
// Returns the number of "buckets" within the `node_hash_set`. Note that
- // because a flat hash map contains all elements within its internal storage,
+ // because a node hash set contains all elements within its internal storage,
// this value simply equals the current capacity of the `node_hash_set`.
using Base::bucket_count;
// node_hash_set::load_factor()
//
// Returns the current load factor of the `node_hash_set` (the average number
- // of slots occupied with a value within the hash map).
+ // of slots occupied with a value within the hash set).
using Base::load_factor;
// node_hash_set::max_load_factor()
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index 78d6da74..6e5c4e87 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -376,9 +376,13 @@ cc_binary(
"flag_benchmark.cc",
],
copts = ABSL_TEST_COPTS,
+ linkopts = select({
+ "//conditions:default": [],
+ }) + ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
+ "flag_benchmark.lds",
":flag",
":marshalling",
":parse",
diff --git a/absl/flags/flag_benchmark.cc b/absl/flags/flag_benchmark.cc
index 9982b604..57584f85 100644
--- a/absl/flags/flag_benchmark.cc
+++ b/absl/flags/flag_benchmark.cc
@@ -103,8 +103,17 @@ std::string AbslUnparseFlag(const UDT&) { return ""; }
#define FLAG_DEF(T) ABSL_FLAG(T, T##_flag, {}, "");
+#if defined(__clang__) && defined(__linux__)
+// Force the flags used for benchmarks into a separate ELF section.
+// This ensures that, even when other parts of the code might change size,
+// the layout of the flags across cachelines is kept constant. This makes
+// benchmark results more reproducible across unrelated code changes.
+#pragma clang section data = ".benchmark_flags"
+#endif
BENCHMARKED_TYPES(FLAG_DEF)
-
+#if defined(__clang__) && defined(__linux__)
+#pragma clang section data = ""
+#endif
// Register thousands of flags to bloat up the size of the registry.
// This mimics real life production binaries.
#define DEFINE_FLAG_0(name) ABSL_FLAG(int, name, 0, "");
@@ -130,7 +139,7 @@ namespace {
benchmark::DoNotOptimize(absl::GetFlag(FLAGS_##T##_flag)); \
} \
} \
- BENCHMARK(BM_GetFlag_##T);
+ BENCHMARK(BM_GetFlag_##T)->ThreadRange(1, 16);
BENCHMARKED_TYPES(BM_GetFlag)
diff --git a/absl/flags/flag_benchmark.lds b/absl/flags/flag_benchmark.lds
new file mode 100644
index 00000000..af115dfc
--- /dev/null
+++ b/absl/flags/flag_benchmark.lds
@@ -0,0 +1,13 @@
+/* This linker script forces the flags used by flags_benchmark
+ * into a separate page-aligned section. This isn't necessary for
+ * correctness but ensures that the benchmark results are more
+ * reproducible across unrelated code changes.
+ */
+SECTIONS {
+ .benchmark_flags : {
+ . = ALIGN(0x1000);
+ * (.benchmark_flags);
+ }
+}
+
+INSERT AFTER .data
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 8d51c750..7cadf75d 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -58,6 +58,7 @@ using ::absl::cord_internal::kMaxFlatLength;
using ::absl::cord_internal::CONCAT;
using ::absl::cord_internal::EXTERNAL;
using ::absl::cord_internal::FLAT;
+using ::absl::cord_internal::RING;
using ::absl::cord_internal::SUBSTRING;
using ::absl::cord_internal::kInlinedVectorSize;