|
2 | 2 |
|
3 | 3 | #include <benchmark/benchmark.h> |
4 | 4 |
|
| 5 | +#include <array> |
| 6 | +#include <cstddef> |
5 | 7 | #include <string> |
| 8 | +#include <thread> |
6 | 9 |
|
| 10 | +// clang-format off |
7 | 11 | /** |
8 | 12 | Results on release build with CPU scaling disabled |
9 | 13 | c++ (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0 |
10 | 14 |
|
11 | | - 2025-06-13T00:17:30+03:00 |
12 | | - Running ./tests/channel_benchmark |
13 | | - Run on (8 X 3999.91 MHz CPU s) |
| 15 | + 2025-06-17T18:36:15+03:00 |
| 16 | + Running ./benchmarks/channel_benchmark |
| 17 | + Run on (8 X 3998.1 MHz CPU s) |
14 | 18 | CPU Caches: |
15 | 19 | L1 Data 32 KiB (x4) |
16 | 20 | L1 Instruction 32 KiB (x4) |
17 | 21 | L2 Unified 256 KiB (x4) |
18 | 22 | L3 Unified 8192 KiB (x1) |
19 | | - Load Average: 2.65, 1.61, 1.50 |
20 | | - ------------------------------------------------------------------------------ |
21 | | - Benchmark Time CPU Iterations |
22 | | - ------------------------------------------------------------------------------ |
23 | | - channel_with_queue_storage 42602 ns 42598 ns 16407 |
24 | | - channel_with_vector_storage 42724 ns 42723 ns 16288 |
25 | | - channel_with_vector_storage 51332 ns 51328 ns 11776 |
| 23 | + Load Average: 1.39, 1.23, 0.98 |
| 24 | + ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| 25 | + Benchmark Time CPU Iterations |
| 26 | + ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| 27 | + bench_dynamic_storage<std::string, msd::queue_storage<std::string>, string_input>_mean 1135532785 ns 1102075601 ns 10 |
| 28 | + bench_dynamic_storage<std::string, msd::queue_storage<std::string>, string_input>_median 1126981431 ns 1096525909 ns 10 |
| 29 | + bench_dynamic_storage<std::string, msd::queue_storage<std::string>, string_input>_stddev 16748064 ns 13438856 ns 10 |
| 30 | + bench_dynamic_storage<std::string, msd::queue_storage<std::string>, string_input>_cv 1.47 % 1.22 % 10 |
| 31 | + bench_dynamic_storage<std::string, msd::vector_storage<std::string>, string_input>_mean 1349502195 ns 1312254745 ns 10 |
| 32 | + bench_dynamic_storage<std::string, msd::vector_storage<std::string>, string_input>_median 1343862530 ns 1309941538 ns 10 |
| 33 | + bench_dynamic_storage<std::string, msd::vector_storage<std::string>, string_input>_stddev 24872877 ns 17496752 ns 10 |
| 34 | + bench_dynamic_storage<std::string, msd::vector_storage<std::string>, string_input>_cv 1.84 % 1.33 % 10 |
| 35 | + bench_static_storage<std::string, msd::array_storage<std::string, channel_capacity>, string_input>_mean 1116143998 ns 1083327478 ns 10 |
| 36 | + bench_static_storage<std::string, msd::array_storage<std::string, channel_capacity>, string_input>_median 1100725718 ns 1069640108 ns 10 |
| 37 | + bench_static_storage<std::string, msd::array_storage<std::string, channel_capacity>, string_input>_stddev 27816556 ns 24827916 ns 10 |
| 38 | + bench_static_storage<std::string, msd::array_storage<std::string, channel_capacity>, string_input>_cv 2.49 % 2.29 % 10 |
| 39 | + bench_dynamic_storage<data, msd::queue_storage<data>, data_input>_mean 110 ns 106 ns 10 |
| 40 | + bench_dynamic_storage<data, msd::queue_storage<data>, data_input>_median 110 ns 106 ns 10 |
| 41 | + bench_dynamic_storage<data, msd::queue_storage<data>, data_input>_stddev 0.279 ns 0.298 ns 10 |
| 42 | + bench_dynamic_storage<data, msd::queue_storage<data>, data_input>_cv 0.25 % 0.28 % 10 |
| 43 | + bench_dynamic_storage<data, msd::vector_storage<data>, data_input>_mean 274 ns 266 ns 10 |
| 44 | + bench_dynamic_storage<data, msd::vector_storage<data>, data_input>_median 276 ns 267 ns 10 |
| 45 | + bench_dynamic_storage<data, msd::vector_storage<data>, data_input>_stddev 11.2 ns 10.9 ns 10 |
| 46 | + bench_dynamic_storage<data, msd::vector_storage<data>, data_input>_cv 4.07 % 4.11 % 10 |
| 47 | + bench_static_storage<data, msd::array_storage<data, channel_capacity>, data_input>_mean 104 ns 102 ns 10 |
| 48 | + bench_static_storage<data, msd::array_storage<data, channel_capacity>, data_input>_median 104 ns 102 ns 10 |
| 49 | + bench_static_storage<data, msd::array_storage<data, channel_capacity>, data_input>_stddev 0.619 ns 0.304 ns 10 |
| 50 | + bench_static_storage<data, msd::array_storage<data, channel_capacity>, data_input>_cv 0.60 % 0.30 % 10 |
26 | 51 | */ |
| 52 | +// clang-format on |
27 | 53 |
|
28 | | -static void channel_with_queue_storage(benchmark::State& state) |
29 | | -{ |
30 | | - msd::channel<std::string, msd::queue_storage<std::string>> channel{10}; |
| 54 | +static constexpr std::size_t channel_capacity = 1024; |
| 55 | +static constexpr std::size_t number_of_inputs = 100000; |
31 | 56 |
|
32 | | - std::string input(1000000, 'x'); |
33 | | - std::string out{}; |
34 | | - out.resize(input.size()); |
| 57 | +struct data { |
| 58 | + std::array<int, 1000> data{}; |
| 59 | +}; |
35 | 60 |
|
36 | | - for (auto _ : state) { |
37 | | - benchmark::DoNotOptimize(channel << input); |
38 | | - benchmark::DoNotOptimize(channel >> out); |
39 | | - } |
40 | | -} |
| 61 | +struct data_input { |
| 62 | + static data make() { return data{}; } |
| 63 | +}; |
41 | 64 |
|
42 | | -BENCHMARK(channel_with_queue_storage); |
| 65 | +struct string_input { |
| 66 | + static std::string make() { return std::string(100000, 'c'); } |
| 67 | +}; |
43 | 68 |
|
44 | | -static void channel_with_vector_storage(benchmark::State& state) |
| 69 | +template <typename T, typename Storage, typename Input> |
| 70 | +static void bench_dynamic_storage(benchmark::State& state) |
45 | 71 | { |
46 | | - msd::channel<std::string, msd::vector_storage<std::string>> channel{10}; |
| 72 | + msd::channel<T, Storage> channel{channel_capacity}; |
| 73 | + const auto input = Input::make(); |
47 | 74 |
|
48 | | - std::string input(1000000, 'x'); |
49 | | - std::string out{}; |
50 | | - out.resize(input.size()); |
| 75 | + std::thread producer([&] { |
| 76 | + for (std::size_t i = 0; i < number_of_inputs; ++i) { |
| 77 | + channel << input; |
| 78 | + } |
| 79 | + channel.close(); |
| 80 | + }); |
51 | 81 |
|
52 | 82 | for (auto _ : state) { |
53 | | - benchmark::DoNotOptimize(channel << input); |
54 | | - benchmark::DoNotOptimize(channel >> out); |
| 83 | + for (auto value : channel) { |
| 84 | + benchmark::DoNotOptimize(value); |
| 85 | + } |
55 | 86 | } |
56 | | -} |
57 | 87 |
|
58 | | -BENCHMARK(channel_with_vector_storage); |
| 88 | + producer.join(); |
| 89 | +} |
59 | 90 |
|
60 | | -static void channel_with_array_storage(benchmark::State& state) |
| 91 | +template <typename T, typename Storage, typename Input> |
| 92 | +static void bench_static_storage(benchmark::State& state) |
61 | 93 | { |
62 | | - msd::channel<std::string, msd::array_storage<std::string, 10>> channel{}; |
| 94 | + msd::channel<T, Storage> channel{}; |
| 95 | + const auto input = Input::make(); |
63 | 96 |
|
64 | | - std::string input(1000000, 'x'); |
65 | | - std::string out{}; |
66 | | - out.resize(input.size()); |
| 97 | + std::thread producer([&] { |
| 98 | + for (std::size_t i = 0; i < number_of_inputs; ++i) { |
| 99 | + channel << input; |
| 100 | + } |
| 101 | + channel.close(); |
| 102 | + }); |
67 | 103 |
|
68 | 104 | for (auto _ : state) { |
69 | | - benchmark::DoNotOptimize(channel << input); |
70 | | - benchmark::DoNotOptimize(channel >> out); |
| 105 | + for (auto value : channel) { |
| 106 | + benchmark::DoNotOptimize(value); |
| 107 | + } |
71 | 108 | } |
| 109 | + |
| 110 | + producer.join(); |
72 | 111 | } |
73 | 112 |
|
74 | | -BENCHMARK(channel_with_array_storage); |
| 113 | +BENCHMARK_TEMPLATE(bench_dynamic_storage, std::string, msd::queue_storage<std::string>, string_input); |
| 114 | +BENCHMARK_TEMPLATE(bench_dynamic_storage, std::string, msd::vector_storage<std::string>, string_input); |
| 115 | +BENCHMARK_TEMPLATE(bench_static_storage, std::string, msd::array_storage<std::string, channel_capacity>, string_input); |
| 116 | +BENCHMARK_TEMPLATE(bench_dynamic_storage, data, msd::queue_storage<data>, data_input); |
| 117 | +BENCHMARK_TEMPLATE(bench_dynamic_storage, data, msd::vector_storage<data>, data_input); |
| 118 | +BENCHMARK_TEMPLATE(bench_static_storage, data, msd::array_storage<data, channel_capacity>, data_input); |
75 | 119 |
|
76 | 120 | BENCHMARK_MAIN(); |
0 commit comments