ソースを参照

Add a build of `boost_unordered` for benchmarking. (#4045)

This uses a header-only extraction of the Boost unordered hashtable
project to allow a trivial Bazel build and for us to benchmark against
it effectively.
Chandler Carruth 1 年間 前
コミット
26ead9addc

+ 10 - 0
MODULE.bazel

@@ -95,6 +95,16 @@ git_override(
     remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git",
 )
 
+boost_unordered_version = "1.85.0"
+
+http_archive(
+    name = "boost_unordered",
+    build_file = "@//:third_party/boost_unordered/BUILD.bazel",
+    integrity = "sha256-2dQ4IQH/xFiK1iWCkrMYLeR8zsSQqGchKOdTuf1u0zI=",
+    strip_prefix = "boost_unordered-{0}".format(boost_unordered_version),
+    urls = ["https://github.com/MikePopoloski/boost_unordered/archive/v{0}.tar.gz".format(boost_unordered_version)],
+)
+
 # Required for llvm-project.
 bazel_dep(name = "platforms", version = "0.0.8")
 bazel_dep(name = "zlib", version = "1.3.1.bcr.1", repo_name = "llvm_zlib")

+ 24 - 5
MODULE.bazel.lock

@@ -1,6 +1,6 @@
 {
   "lockFileVersion": 6,
-  "moduleFileHash": "439583f1efb19cfa4ef173e2ac4774602be6be5061bc14218f9856f4beb33e07",
+  "moduleFileHash": "2229e2fa995d00859c76832081e78c1260d43da826c71273e51f34182539eafd",
   "flags": {
     "cmdRegistries": [
       "https://bcr.bazel.build/"
@@ -37,6 +37,7 @@
           },
           "imports": {
             "com_google_libprotobuf_mutator": "com_google_libprotobuf_mutator",
+            "boost_unordered": "boost_unordered",
             "llvm-raw": "llvm-raw"
           },
           "devImports": [],
@@ -59,6 +60,24 @@
                 "column": 13
               }
             },
+            {
+              "tagName": "@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
+              "attributeValues": {
+                "build_file": "@//:third_party/boost_unordered/BUILD.bazel",
+                "integrity": "sha256-2dQ4IQH/xFiK1iWCkrMYLeR8zsSQqGchKOdTuf1u0zI=",
+                "strip_prefix": "boost_unordered-1.85.0",
+                "urls": [
+                  "https://github.com/MikePopoloski/boost_unordered/archive/v1.85.0.tar.gz"
+                ],
+                "name": "boost_unordered"
+              },
+              "devDependency": false,
+              "location": {
+                "file": "@@//:MODULE.bazel",
+                "line": 100,
+                "column": 13
+              }
+            },
             {
               "tagName": "@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
               "attributeValues": {
@@ -80,7 +99,7 @@
               "devDependency": false,
               "location": {
                 "file": "@@//:MODULE.bazel",
-                "line": 113,
+                "line": 123,
                 "column": 13
               }
             }
@@ -111,7 +130,7 @@
           "usingModule": "<root>",
           "location": {
             "file": "@@//:MODULE.bazel",
-            "line": 127,
+            "line": 137,
             "column": 29
           },
           "imports": {
@@ -128,7 +147,7 @@
           "usingModule": "<root>",
           "location": {
             "file": "@@//:MODULE.bazel",
-            "line": 139,
+            "line": 149,
             "column": 23
           },
           "imports": {
@@ -144,7 +163,7 @@
               "devDependency": false,
               "location": {
                 "file": "@@//:MODULE.bazel",
-                "line": 140,
+                "line": 150,
                 "column": 17
               }
             }

+ 1 - 0
bazel/cc_toolchains/clang_cc_toolchain_config.bzl

@@ -149,6 +149,7 @@ def _impl(ctx):
                             # to be initial directories in the `#include` line.
                             "--system-header-prefix=absl/",
                             "--system-header-prefix=benchmark/",
+                            "--system-header-prefix=boost/",
                             "--system-header-prefix=clang-tools-extra/",
                             "--system-header-prefix=clang/",
                             "--system-header-prefix=gmock/",

+ 1 - 0
common/BUILD

@@ -264,6 +264,7 @@ cc_binary(
         ":raw_hashtable_benchmark_helpers",
         "@abseil-cpp//absl/container:flat_hash_map",
         "@abseil-cpp//absl/random",
+        "@boost_unordered",
         "@google_benchmark//:benchmark_main",
         "@llvm-project//llvm:Support",
     ],

+ 13 - 4
common/map_benchmark.cpp

@@ -4,6 +4,7 @@
 
 #include <benchmark/benchmark.h>
 
+#include <boost/unordered/unordered_flat_map.hpp>
 #include <type_traits>
 
 #include "absl/container/flat_hash_map.h"
@@ -133,6 +134,7 @@ struct MapWrapperImpl<Map<KT, VT, MinSmallSize>> {
 enum class MapOverride : uint8_t {
   None,
   Abseil,
+  Boost,
   LLVM,
   LLVMAndCarbonHash,
 };
@@ -147,6 +149,10 @@ template <typename KeyT, typename ValueT, int MinSmallSize>
 struct MapWrapperOverride<Map<KeyT, ValueT, MinSmallSize>, MapOverride::Abseil>
     : MapWrapperImpl<absl::flat_hash_map<KeyT, ValueT>> {};
 
+template <typename KeyT, typename ValueT, int MinSmallSize>
+struct MapWrapperOverride<Map<KeyT, ValueT, MinSmallSize>, MapOverride::Boost>
+    : MapWrapperImpl<boost::unordered::unordered_flat_map<KeyT, ValueT>> {};
+
 template <typename KeyT, typename ValueT, int MinSmallSize>
 struct MapWrapperOverride<Map<KeyT, ValueT, MinSmallSize>, MapOverride::LLVM>
     : MapWrapperImpl<llvm::DenseMap<KeyT, ValueT>> {};
@@ -170,10 +176,11 @@ auto ReportMetrics(const MapWrapper<MapT>& m_wrapper, benchmark::State& state)
 }
 
 // NOLINTBEGIN(bugprone-macro-parentheses): Parentheses are incorrect here.
-#define MAP_BENCHMARK_ONE_OP_SIZE(NAME, APPLY, KT, VT)        \
-  BENCHMARK(NAME<Map<KT, VT>>)->Apply(APPLY);                 \
-  BENCHMARK(NAME<absl::flat_hash_map<KT, VT>>)->Apply(APPLY); \
-  BENCHMARK(NAME<llvm::DenseMap<KT, VT>>)->Apply(APPLY);      \
+#define MAP_BENCHMARK_ONE_OP_SIZE(NAME, APPLY, KT, VT)                         \
+  BENCHMARK(NAME<Map<KT, VT>>)->Apply(APPLY);                                  \
+  BENCHMARK(NAME<absl::flat_hash_map<KT, VT>>)->Apply(APPLY);                  \
+  BENCHMARK(NAME<boost::unordered::unordered_flat_map<KT, VT>>)->Apply(APPLY); \
+  BENCHMARK(NAME<llvm::DenseMap<KT, VT>>)->Apply(APPLY);                       \
   BENCHMARK(NAME<llvm::DenseMap<KT, VT, CarbonHashDI<KT>>>)->Apply(APPLY)
 // NOLINTEND(bugprone-macro-parentheses)
 
@@ -407,6 +414,8 @@ MAP_BENCHMARK_ONE_OP(BM_MapEraseUpdateHit, HitArgs);
 #define MAP_BENCHMARK_OP_SEQ_SIZE(NAME, KT, VT)                  \
   BENCHMARK(NAME<Map<KT, VT>>)->Apply(SizeArgs);                 \
   BENCHMARK(NAME<absl::flat_hash_map<KT, VT>>)->Apply(SizeArgs); \
+  BENCHMARK(NAME<boost::unordered::unordered_flat_map<KT, VT>>)  \
+      ->Apply(SizeArgs);                                         \
   BENCHMARK(NAME<llvm::DenseMap<KT, VT>>)->Apply(APPLY);         \
   BENCHMARK(NAME<llvm::DenseMap<KT, VT, CarbonHashDI<KT>>>)->Apply(SizeArgs)
 // NOLINTEND(bugprone-macro-parentheses)

+ 6 - 0
scripts/fix_cc_deps.py

@@ -71,6 +71,12 @@ EXTERNAL_REPOS: Dict[str, ExternalRepo] = {
         ":gtest",
         use_system_include=True,
     ),
+    # All of the `boost_unordered` headers are in a single rule.
+    "@boost_unordered": ExternalRepo(
+        lambda x: re.sub("^(.*:include)/", "", x),
+        ":boost_unordered",
+        use_system_include=True,
+    ),
 }
 
 # TODO: proto rules are aspect-based and their generated files don't show up in

+ 14 - 0
third_party/boost_unordered/BUILD.bazel

@@ -0,0 +1,14 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+load("@rules_cc//cc:defs.bzl", "cc_library")
+
+exports_files(["LICENSE"])
+
+cc_library(
+    name = "boost_unordered",
+    hdrs = glob(["include/boost/**/*.hpp"]),
+    strip_include_prefix = "include",
+    visibility = ["//visibility:public"],
+)