From: Jacob Lifshay Date: Wed, 27 Jul 2022 01:57:29 +0000 (-0700) Subject: split c11_atomics_benchmarks.cpp up in an attempt to improve compile time X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=520ccbd65771b9e6c422388bfef39f82f4a4076c;p=benchmarks.git split c11_atomics_benchmarks.cpp up in an attempt to improve compile time --- diff --git a/src/common/c11_atomics/c11_atomics_benchmarks.cpp b/src/common/c11_atomics/c11_atomics_benchmarks.cpp index 20d02b0..e6d18fb 100644 --- a/src/common/c11_atomics/c11_atomics_benchmarks.cpp +++ b/src/common/c11_atomics/c11_atomics_benchmarks.cpp @@ -1,216 +1,9 @@ #include "c11_atomics_benchmarks.h" -#include -#include -#include -#include -#include -#include - -template struct IntTypeName; - -template -inline constexpr std::string_view int_type_name = IntTypeName::name; - -#define INT_TYPE_NAME(sz, ui, uint) \ - template <> struct IntTypeName final \ - { \ - static constexpr std::string_view name = #ui #sz; \ - }; - -INT_TYPE_NAME(8, u, uint) -INT_TYPE_NAME(16, u, uint) -INT_TYPE_NAME(32, u, uint) -INT_TYPE_NAME(64, u, uint) -INT_TYPE_NAME(8, i, int) -INT_TYPE_NAME(16, i, int) -INT_TYPE_NAME(32, i, int) -INT_TYPE_NAME(64, i, int) - -template struct MemoryOrderName; - -template -inline constexpr std::string_view memory_order_name = - MemoryOrderName::name; - -#define MEMORY_ORDER_NAME(order) \ - template <> struct MemoryOrderName final \ - { \ - static constexpr std::string_view name = #order; \ - }; - -MEMORY_ORDER_NAME(relaxed) -MEMORY_ORDER_NAME(acquire) -MEMORY_ORDER_NAME(release) -MEMORY_ORDER_NAME(acq_rel) -MEMORY_ORDER_NAME(seq_cst) - -template using Buf = std::shared_ptr>>; - -template -static void push_atomic_bench(std::vector &benches, - const Config &config, Buf buf, Fn fn, - NameParts &&...name_parts) -{ - auto log2_stride = config.log2_stride; - std::size_t index_mask = 1; - index_mask <<= config.log2_stride; - index_mask <<= config.log2_memory_location_count; - index_mask--; - push_bench( - benches, - [buf, fn, index_mask, log2_stride](T input, std::uint64_t iteration, - std::uint32_t thread_num) { - std::size_t index = iteration; - index ^= static_cast(thread_num) * 0x12345; - index <<= log2_stride; - index &= index_mask; - std::atomic *atomic = &(*buf)[index]; - input ^= static_cast(iteration); - return fn(input, atomic, iteration ^ thread_num); - }, - T{}, name_parts...); -} - -template -static void rmw_benchmarks(std::vector &benches, - const Config &config, Buf buf) -{ - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_exchange_explicit(atomic, input, order); - }, - "atomic_exchange_", int_type_name, "_", memory_order_name); - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_fetch_add_explicit(atomic, input, order); - }, - "atomic_fetch_add_", int_type_name, "_", memory_order_name); - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_fetch_sub_explicit(atomic, input, order); - }, - "atomic_fetch_sub_", int_type_name, "_", memory_order_name); - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_fetch_and_explicit(atomic, input, order); - }, - "atomic_fetch_and_", int_type_name, "_", memory_order_name); - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_fetch_or_explicit(atomic, input, order); - }, - "atomic_fetch_or_", int_type_name, "_", memory_order_name); - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_fetch_xor_explicit(atomic, input, order); - }, - "atomic_fetch_xor_", int_type_name, "_", memory_order_name); -} - -template -static void load_benchmarks(std::vector &benches, - const Config &config, Buf buf) -{ - push_atomic_bench( - benches, config, buf, - [](T, std::atomic *atomic, std::uint64_t) { - return std::atomic_load_explicit(atomic, order); - }, - "atomic_load_", int_type_name, "_", memory_order_name); -} - -template -static void store_benchmarks(std::vector &benches, - const Config &config, Buf buf) -{ - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t) { - return std::atomic_store_explicit(atomic, input, order); - }, - "atomic_store_", int_type_name, "_", memory_order_name); -} - -template -static void cmp_xchg_benchmarks(std::vector &benches, - const Config &config, Buf buf) -{ - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t state) { - T expected = state; - bool succeeded = std::atomic_compare_exchange_weak_explicit( - atomic, &expected, input, succ, fail); - return std::pair(expected, succeeded); - }, - "atomic_compare_exchange_weak_", int_type_name, "_", - memory_order_name, "_", memory_order_name); - push_atomic_bench( - benches, config, buf, - [](T input, std::atomic *atomic, std::uint64_t state) { - T expected = state; - bool succeeded = std::atomic_compare_exchange_strong_explicit( - atomic, &expected, input, succ, fail); - return std::pair(expected, succeeded); - }, - "atomic_compare_exchange_strong_", int_type_name, "_", - memory_order_name, "_", memory_order_name); -} - -template -static void benchmarks(std::vector &benches, const Config &config) -{ - std::size_t buf_size = 1; - buf_size <<= config.log2_memory_location_count; - buf_size <<= config.log2_stride; - Buf buf = std::make_shared>>(buf_size); - - rmw_benchmarks(benches, config, buf); - rmw_benchmarks(benches, config, buf); - rmw_benchmarks(benches, config, buf); - rmw_benchmarks(benches, config, buf); - rmw_benchmarks(benches, config, buf); - - load_benchmarks(benches, config, buf); - load_benchmarks(benches, config, buf); - load_benchmarks(benches, config, buf); - - store_benchmarks(benches, config, buf); - store_benchmarks(benches, config, buf); - store_benchmarks(benches, config, buf); - - cmp_xchg_benchmarks(benches, config, buf); - - cmp_xchg_benchmarks(benches, config, buf); - cmp_xchg_benchmarks(benches, config, buf); - - cmp_xchg_benchmarks(benches, config, buf); - - cmp_xchg_benchmarks(benches, config, buf); - cmp_xchg_benchmarks(benches, config, buf); - - cmp_xchg_benchmarks(benches, config, buf); - cmp_xchg_benchmarks(benches, config, buf); - cmp_xchg_benchmarks(benches, config, buf); -} +#include "internals.h" std::vector c11_atomics_benchmarks(const Config &config) { + using namespace c11_atomics; std::vector benches; benchmarks(benches, config); benchmarks(benches, config); diff --git a/src/common/c11_atomics/i16.cpp b/src/common/c11_atomics/i16.cpp new file mode 100644 index 0000000..a84f360 --- /dev/null +++ b/src/common/c11_atomics/i16.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/i32.cpp b/src/common/c11_atomics/i32.cpp new file mode 100644 index 0000000..5cf88db --- /dev/null +++ b/src/common/c11_atomics/i32.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/i64.cpp b/src/common/c11_atomics/i64.cpp new file mode 100644 index 0000000..30bc0f7 --- /dev/null +++ b/src/common/c11_atomics/i64.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/i8.cpp b/src/common/c11_atomics/i8.cpp new file mode 100644 index 0000000..6cf1c42 --- /dev/null +++ b/src/common/c11_atomics/i8.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/internals.h b/src/common/c11_atomics/internals.h new file mode 100644 index 0000000..7640ee6 --- /dev/null +++ b/src/common/c11_atomics/internals.h @@ -0,0 +1,232 @@ +#pragma once + +#include "../../harness.h" +#include +#include + +namespace c11_atomics +{ + +template struct IntTypeName; + +template +inline constexpr std::string_view int_type_name = IntTypeName::name; + +#define INT_TYPE_NAME(sz, ui, uint) \ + template <> struct IntTypeName final \ + { \ + static constexpr std::string_view name = #ui #sz; \ + }; + +INT_TYPE_NAME(8, u, uint) +INT_TYPE_NAME(16, u, uint) +INT_TYPE_NAME(32, u, uint) +INT_TYPE_NAME(64, u, uint) +INT_TYPE_NAME(8, i, int) +INT_TYPE_NAME(16, i, int) +INT_TYPE_NAME(32, i, int) +INT_TYPE_NAME(64, i, int) + +template struct MemoryOrderName; + +template +inline constexpr std::string_view memory_order_name = + MemoryOrderName::name; + +#define MEMORY_ORDER_NAME(order) \ + template <> struct MemoryOrderName final \ + { \ + static constexpr std::string_view name = #order; \ + }; + +MEMORY_ORDER_NAME(relaxed) +MEMORY_ORDER_NAME(acquire) +MEMORY_ORDER_NAME(release) +MEMORY_ORDER_NAME(acq_rel) +MEMORY_ORDER_NAME(seq_cst) + +template using Buf = std::shared_ptr>>; + +template +static void push_atomic_bench(std::vector &benches, + const Config &config, Buf buf, Fn fn, + NameParts &&...name_parts) +{ + auto log2_stride = config.log2_stride; + std::size_t index_mask = 1; + index_mask <<= config.log2_stride; + index_mask <<= config.log2_memory_location_count; + index_mask--; + push_bench( + benches, + [buf, fn, index_mask, log2_stride](T input, std::uint64_t iteration, + std::uint32_t thread_num) { + std::size_t index = iteration; + index ^= static_cast(thread_num) * 0x12345; + index <<= log2_stride; + index &= index_mask; + std::atomic *atomic = &(*buf)[index]; + input ^= static_cast(iteration); + return fn(input, atomic, iteration ^ thread_num); + }, + T{}, name_parts...); +} + +template +static void rmw_benchmarks(std::vector &benches, + const Config &config, Buf buf) +{ + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_exchange_explicit(atomic, input, order); + }, + "atomic_exchange_", int_type_name, "_", memory_order_name); + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_fetch_add_explicit(atomic, input, order); + }, + "atomic_fetch_add_", int_type_name, "_", memory_order_name); + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_fetch_sub_explicit(atomic, input, order); + }, + "atomic_fetch_sub_", int_type_name, "_", memory_order_name); + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_fetch_and_explicit(atomic, input, order); + }, + "atomic_fetch_and_", int_type_name, "_", memory_order_name); + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_fetch_or_explicit(atomic, input, order); + }, + "atomic_fetch_or_", int_type_name, "_", memory_order_name); + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_fetch_xor_explicit(atomic, input, order); + }, + "atomic_fetch_xor_", int_type_name, "_", memory_order_name); +} + +template +static void load_benchmarks(std::vector &benches, + const Config &config, Buf buf) +{ + push_atomic_bench( + benches, config, buf, + [](T, std::atomic *atomic, std::uint64_t) { + return std::atomic_load_explicit(atomic, order); + }, + "atomic_load_", int_type_name, "_", memory_order_name); +} + +template +static void store_benchmarks(std::vector &benches, + const Config &config, Buf buf) +{ + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t) { + return std::atomic_store_explicit(atomic, input, order); + }, + "atomic_store_", int_type_name, "_", memory_order_name); +} + +template +static void cmp_xchg_benchmarks(std::vector &benches, + const Config &config, Buf buf) +{ + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t state) { + T expected = state; + bool succeeded = std::atomic_compare_exchange_weak_explicit( + atomic, &expected, input, succ, fail); + return std::pair(expected, succeeded); + }, + "atomic_compare_exchange_weak_", int_type_name, "_", + memory_order_name, "_", memory_order_name); + push_atomic_bench( + benches, config, buf, + [](T input, std::atomic *atomic, std::uint64_t state) { + T expected = state; + bool succeeded = std::atomic_compare_exchange_strong_explicit( + atomic, &expected, input, succ, fail); + return std::pair(expected, succeeded); + }, + "atomic_compare_exchange_strong_", int_type_name, "_", + memory_order_name, "_", memory_order_name); +} + +template +void benchmarks(std::vector &benches, const Config &config) +{ + std::size_t buf_size = 1; + buf_size <<= config.log2_memory_location_count; + buf_size <<= config.log2_stride; + Buf buf = std::make_shared>>(buf_size); + + rmw_benchmarks(benches, config, buf); + rmw_benchmarks(benches, config, buf); + rmw_benchmarks(benches, config, buf); + rmw_benchmarks(benches, config, buf); + rmw_benchmarks(benches, config, buf); + + load_benchmarks(benches, config, buf); + load_benchmarks(benches, config, buf); + load_benchmarks(benches, config, buf); + + store_benchmarks(benches, config, buf); + store_benchmarks(benches, config, buf); + store_benchmarks(benches, config, buf); + + cmp_xchg_benchmarks(benches, config, buf); + + cmp_xchg_benchmarks(benches, config, buf); + cmp_xchg_benchmarks(benches, config, buf); + + cmp_xchg_benchmarks(benches, config, buf); + + cmp_xchg_benchmarks(benches, config, buf); + cmp_xchg_benchmarks(benches, config, buf); + + cmp_xchg_benchmarks(benches, config, buf); + cmp_xchg_benchmarks(benches, config, buf); + cmp_xchg_benchmarks(benches, config, buf); +} + +#define C11_ATOMICS_TYPES \ + C11_ATOMICS_TYPE(std::uint8_t) \ + C11_ATOMICS_TYPE(std::uint16_t) \ + C11_ATOMICS_TYPE(std::uint32_t) \ + C11_ATOMICS_TYPE(std::uint64_t) \ + C11_ATOMICS_TYPE(std::int8_t) \ + C11_ATOMICS_TYPE(std::int16_t) \ + C11_ATOMICS_TYPE(std::int32_t) \ + C11_ATOMICS_TYPE(std::int64_t) \ + // + +#define C11_ATOMICS_TYPE(T) \ + extern template void benchmarks(std::vector & benches, \ + const Config &config); + +C11_ATOMICS_TYPES + +#undef C11_ATOMICS_TYPE + +} // namespace c11_atomics \ No newline at end of file diff --git a/src/common/c11_atomics/u16.cpp b/src/common/c11_atomics/u16.cpp new file mode 100644 index 0000000..f2b4f2f --- /dev/null +++ b/src/common/c11_atomics/u16.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/u32.cpp b/src/common/c11_atomics/u32.cpp new file mode 100644 index 0000000..3f4dca2 --- /dev/null +++ b/src/common/c11_atomics/u32.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/u64.cpp b/src/common/c11_atomics/u64.cpp new file mode 100644 index 0000000..7596bc5 --- /dev/null +++ b/src/common/c11_atomics/u64.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config); diff --git a/src/common/c11_atomics/u8.cpp b/src/common/c11_atomics/u8.cpp new file mode 100644 index 0000000..1553065 --- /dev/null +++ b/src/common/c11_atomics/u8.cpp @@ -0,0 +1,4 @@ +#include "internals.h" + +template void c11_atomics::benchmarks( + std::vector &benches, const Config &config);