From 435d0d4db56b6657eafc876e13a485e2a99b71aa Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 6 Apr 2019 14:00:14 -0400 Subject: [PATCH] add bench in examples --- CMakeLists.txt | 11 ++- examples/insert_bench.cc | 141 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 examples/insert_bench.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 01c97ae..52cfa95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,11 +42,15 @@ option(PHMAP_BUILD_TESTS "Whether or not to build the tests" OFF) option(PHMAP_BUILD_EXAMPLES "Whether or not to build the examples" OFF) if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_GENERATOR_PLATFORM "x64") + endif() + elseif(CXXFLAGS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXXFLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXXFLAGS}") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() if (PHMAP_BUILD_TESTS) @@ -112,6 +116,7 @@ if (PHMAP_BUILD_EXAMPLES) add_executable(ex_emplace examples/emplace.cc) add_executable(ex_hash_std examples/hash_std.cc) add_executable(ex_two_files examples/f1.cc examples/f2.cc) + add_executable(ex_insert_bench examples/insert_bench.cc) endif() diff --git a/examples/insert_bench.cc b/examples/insert_bench.cc new file mode 100644 index 0000000..1ab9517 --- /dev/null +++ b/examples/insert_bench.cc @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#define PHMAP_ALLOCATOR_NOTHROW 1 +#include + +// this is probably the fastest high quality 64bit random number generator that exists. +// Implements Small Fast Counting v4 RNG from PractRand. +class sfc64 { +public: + using result_type = uint64_t; + + // no copy ctors so we don't accidentally get the same random again + sfc64(sfc64 const&) = delete; + sfc64& operator=(sfc64 const&) = delete; + + sfc64(sfc64&&) = default; + sfc64& operator=(sfc64&&) = default; + + sfc64(std::array const& state) + : m_a(state[0]) + , m_b(state[1]) + , m_c(state[2]) + , m_counter(state[3]) {} + + static constexpr uint64_t(min)() { + return (std::numeric_limits::min)(); + } + static constexpr uint64_t(max)() { + return (std::numeric_limits::max)(); + } + + sfc64() + : sfc64(UINT64_C(0x853c49e6748fea9b)) {} + + sfc64(uint64_t seed) + : m_a(seed) + , m_b(seed) + , m_c(seed) + , m_counter(1) { + for (int i = 0; i < 12; ++i) { + operator()(); + } + } + + void seed() { + *this = sfc64{std::random_device{}()}; + } + + uint64_t operator()() noexcept { + auto const tmp = m_a + m_b + m_counter++; + m_a = m_b ^ (m_b >> right_shift); + m_b = m_c + (m_c << left_shift); + m_c = rotl(m_c, rotation) + tmp; + return tmp; + } + + // this is a bit biased, but for our use case that's not important. + uint64_t operator()(uint64_t boundExcluded) noexcept { +#ifdef PHMAP_HAS_UMUL128 + uint64_t h; + uint64_t l = umul128(operator()(), boundExcluded, &h); + return h; +#endif + } + + std::array state() const { + return {m_a, m_b, m_c, m_counter}; + } + + void state(std::array const& s) { + m_a = s[0]; + m_b = s[1]; + m_c = s[2]; + m_counter = s[3]; + } + +private: + template + T rotl(T const x, int k) { + return (x << k) | (x >> (8 * sizeof(T) - k)); + } + + static constexpr int rotation = 24; + static constexpr int right_shift = 11; + static constexpr int left_shift = 3; + uint64_t m_a; + uint64_t m_b; + uint64_t m_c; + uint64_t m_counter; +}; + + +int main() +{ + // Create an unordered_map of three strings (that map to strings) + using Map = phmap::parallel_node_hash_map; + static size_t const n = 50000000; + sfc64 rng(123); + + size_t checksum = 0; + + if (0) + { + size_t const max_rng = n / 20; + Map map; + for (size_t i = 0; i < n; ++i) { + checksum += ++map[static_cast(rng(max_rng))]; + } + } + + if (0) + { + size_t const max_rng = n / 4; + Map map; + for (size_t i = 0; i < n; ++i) { + checksum += ++map[static_cast(rng(max_rng))]; + } + } + + if (1) + { + size_t const max_rng = n / 2; + Map map; + for (size_t i = 0; i < n; ++i) { + checksum += ++map[static_cast(rng(max_rng))]; + } + } + + if (0) + { + Map map; + for (size_t i = 0; i < n; ++i) { + checksum += ++map[static_cast(rng())]; + } + } + printf("%d\n", checksum); +}