xref: /llvm-project/libc/benchmarks/LibcMemoryGoogleBenchmarkMain.cpp (revision bcf394c4d1257890dc5add64c6844b8fddae18ef)
159198d06SGuillaume Chatelet #include "LibcBenchmark.h"
259198d06SGuillaume Chatelet #include "LibcMemoryBenchmark.h"
359198d06SGuillaume Chatelet #include "MemorySizeDistributions.h"
459198d06SGuillaume Chatelet #include "benchmark/benchmark.h"
5e4dee762SGuillaume Chatelet #include "llvm/ADT/ArrayRef.h"
6e4dee762SGuillaume Chatelet #include "llvm/ADT/Twine.h"
7e4dee762SGuillaume Chatelet #include <chrono>
859198d06SGuillaume Chatelet #include <cstdint>
959198d06SGuillaume Chatelet #include <random>
1059198d06SGuillaume Chatelet #include <vector>
1159198d06SGuillaume Chatelet 
12e4dee762SGuillaume Chatelet using llvm::Align;
13e4dee762SGuillaume Chatelet using llvm::ArrayRef;
14e4dee762SGuillaume Chatelet using llvm::Twine;
15e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::BzeroConfiguration;
16e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::ComparisonSetup;
17e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::CopySetup;
184a9bcb60SGuillaume Chatelet using llvm::libc_benchmarks::MemcmpOrBcmpConfiguration;
19e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::MemcpyConfiguration;
20de21f346SGuillaume Chatelet using llvm::libc_benchmarks::MemmoveConfiguration;
21e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::MemorySizeDistribution;
22e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::MemsetConfiguration;
23de21f346SGuillaume Chatelet using llvm::libc_benchmarks::MoveSetup;
24e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::OffsetDistribution;
25e4dee762SGuillaume Chatelet using llvm::libc_benchmarks::SetSetup;
26e4dee762SGuillaume Chatelet 
27e4dee762SGuillaume Chatelet // Alignment to use for when accessing the buffers.
2859198d06SGuillaume Chatelet static constexpr Align kBenchmarkAlignment = Align::Constant<1>();
2959198d06SGuillaume Chatelet 
getGenerator()30e4dee762SGuillaume Chatelet static std::mt19937_64 &getGenerator() {
31e4dee762SGuillaume Chatelet   static std::mt19937_64 Generator(
32e4dee762SGuillaume Chatelet       std::chrono::system_clock::now().time_since_epoch().count());
33e4dee762SGuillaume Chatelet   return Generator;
34e4dee762SGuillaume Chatelet }
35e4dee762SGuillaume Chatelet 
36e4dee762SGuillaume Chatelet template <typename SetupType, typename ConfigurationType> struct Runner {
RunnerRunner37e4dee762SGuillaume Chatelet   Runner(benchmark::State &S, llvm::ArrayRef<ConfigurationType> Configurations)
38e4dee762SGuillaume Chatelet       : State(S), Distribution(SetupType::getDistributions()[State.range(0)]),
3959198d06SGuillaume Chatelet         Probabilities(Distribution.Probabilities),
4059198d06SGuillaume Chatelet         SizeSampler(Probabilities.begin(), Probabilities.end()),
41e4dee762SGuillaume Chatelet         OffsetSampler(Setup.BufferSize, Probabilities.size() - 1,
42e4dee762SGuillaume Chatelet                       kBenchmarkAlignment),
43e4dee762SGuillaume Chatelet         Configuration(Configurations[State.range(1)]) {
44e4dee762SGuillaume Chatelet     for (auto &P : Setup.Parameters) {
45e4dee762SGuillaume Chatelet       P.OffsetBytes = OffsetSampler(getGenerator());
46e4dee762SGuillaume Chatelet       P.SizeBytes = SizeSampler(getGenerator());
47e4dee762SGuillaume Chatelet       Setup.checkValid(P);
4859198d06SGuillaume Chatelet     }
4959198d06SGuillaume Chatelet   }
5059198d06SGuillaume Chatelet 
~RunnerRunner51e4dee762SGuillaume Chatelet   ~Runner() {
52*bcf394c4SGuillaume Chatelet     const size_t TotalBytes =
53*bcf394c4SGuillaume Chatelet         (State.iterations() * Setup.getBatchBytes()) / Setup.BatchSize;
5459198d06SGuillaume Chatelet     State.SetBytesProcessed(TotalBytes);
55e4dee762SGuillaume Chatelet     State.SetItemsProcessed(State.iterations());
56e4dee762SGuillaume Chatelet     State.SetLabel((Twine(Configuration.Name) + "," + Distribution.Name).str());
5759198d06SGuillaume Chatelet     State.counters["bytes_per_cycle"] = benchmark::Counter(
5859198d06SGuillaume Chatelet         TotalBytes / benchmark::CPUInfo::Get().cycles_per_second,
5959198d06SGuillaume Chatelet         benchmark::Counter::kIsRate);
6059198d06SGuillaume Chatelet   }
6159198d06SGuillaume Chatelet 
runBatchRunner62e4dee762SGuillaume Chatelet   inline void runBatch() {
63e4dee762SGuillaume Chatelet     for (const auto &P : Setup.Parameters)
64e4dee762SGuillaume Chatelet       benchmark::DoNotOptimize(Setup.Call(P, Configuration.Function));
6559198d06SGuillaume Chatelet   }
6659198d06SGuillaume Chatelet 
getBatchSizeRunner67e4dee762SGuillaume Chatelet   size_t getBatchSize() const { return Setup.BatchSize; }
68e4dee762SGuillaume Chatelet 
6959198d06SGuillaume Chatelet private:
70e4dee762SGuillaume Chatelet   SetupType Setup;
7159198d06SGuillaume Chatelet   benchmark::State &State;
7259198d06SGuillaume Chatelet   MemorySizeDistribution Distribution;
7359198d06SGuillaume Chatelet   ArrayRef<double> Probabilities;
7459198d06SGuillaume Chatelet   std::discrete_distribution<unsigned> SizeSampler;
7559198d06SGuillaume Chatelet   OffsetDistribution OffsetSampler;
76e4dee762SGuillaume Chatelet   ConfigurationType Configuration;
7759198d06SGuillaume Chatelet };
7859198d06SGuillaume Chatelet 
79e4dee762SGuillaume Chatelet #define BENCHMARK_MEMORY_FUNCTION(BM_NAME, SETUP, CONFIGURATION_TYPE,          \
80e4dee762SGuillaume Chatelet                                   CONFIGURATION_ARRAY_REF)                     \
81e4dee762SGuillaume Chatelet   void BM_NAME(benchmark::State &State) {                                      \
82e4dee762SGuillaume Chatelet     Runner<SETUP, CONFIGURATION_TYPE> Setup(State, CONFIGURATION_ARRAY_REF);   \
83e4dee762SGuillaume Chatelet     const size_t BatchSize = Setup.getBatchSize();                             \
84e4dee762SGuillaume Chatelet     while (State.KeepRunningBatch(BatchSize))                                  \
85e4dee762SGuillaume Chatelet       Setup.runBatch();                                                        \
86e4dee762SGuillaume Chatelet   }                                                                            \
87e4dee762SGuillaume Chatelet   BENCHMARK(BM_NAME)->Apply([](benchmark::internal::Benchmark *benchmark) {    \
88e4dee762SGuillaume Chatelet     const int64_t DistributionSize = SETUP::getDistributions().size();         \
89e4dee762SGuillaume Chatelet     const int64_t ConfigurationSize = CONFIGURATION_ARRAY_REF.size();          \
90e4dee762SGuillaume Chatelet     for (int64_t DistIndex = 0; DistIndex < DistributionSize; ++DistIndex)     \
91e4dee762SGuillaume Chatelet       for (int64_t ConfIndex = 0; ConfIndex < ConfigurationSize; ++ConfIndex)  \
92e4dee762SGuillaume Chatelet         benchmark->Args({DistIndex, ConfIndex});                               \
93e4dee762SGuillaume Chatelet   })
9459198d06SGuillaume Chatelet 
95adc18ad6SGuillaume Chatelet extern llvm::ArrayRef<MemcpyConfiguration> getMemcpyConfigurations();
96e4dee762SGuillaume Chatelet BENCHMARK_MEMORY_FUNCTION(BM_Memcpy, CopySetup, MemcpyConfiguration,
97adc18ad6SGuillaume Chatelet                           getMemcpyConfigurations());
98adc18ad6SGuillaume Chatelet 
99de21f346SGuillaume Chatelet extern llvm::ArrayRef<MemmoveConfiguration> getMemmoveConfigurations();
100de21f346SGuillaume Chatelet BENCHMARK_MEMORY_FUNCTION(BM_Memmove, MoveSetup, MemmoveConfiguration,
101de21f346SGuillaume Chatelet                           getMemmoveConfigurations());
102de21f346SGuillaume Chatelet 
1034a9bcb60SGuillaume Chatelet extern llvm::ArrayRef<MemcmpOrBcmpConfiguration> getMemcmpConfigurations();
1044a9bcb60SGuillaume Chatelet BENCHMARK_MEMORY_FUNCTION(BM_Memcmp, ComparisonSetup, MemcmpOrBcmpConfiguration,
105adc18ad6SGuillaume Chatelet                           getMemcmpConfigurations());
106adc18ad6SGuillaume Chatelet 
1074a9bcb60SGuillaume Chatelet extern llvm::ArrayRef<MemcmpOrBcmpConfiguration> getBcmpConfigurations();
1084a9bcb60SGuillaume Chatelet BENCHMARK_MEMORY_FUNCTION(BM_Bcmp, ComparisonSetup, MemcmpOrBcmpConfiguration,
109adc18ad6SGuillaume Chatelet                           getBcmpConfigurations());
110adc18ad6SGuillaume Chatelet 
111adc18ad6SGuillaume Chatelet extern llvm::ArrayRef<MemsetConfiguration> getMemsetConfigurations();
112e4dee762SGuillaume Chatelet BENCHMARK_MEMORY_FUNCTION(BM_Memset, SetSetup, MemsetConfiguration,
113adc18ad6SGuillaume Chatelet                           getMemsetConfigurations());
114adc18ad6SGuillaume Chatelet 
115adc18ad6SGuillaume Chatelet extern llvm::ArrayRef<BzeroConfiguration> getBzeroConfigurations();
116e4dee762SGuillaume Chatelet BENCHMARK_MEMORY_FUNCTION(BM_Bzero, SetSetup, BzeroConfiguration,
117adc18ad6SGuillaume Chatelet                           getBzeroConfigurations());
118