llvm-project
117 строк · 5.0 Кб
1#include "LibcBenchmark.h"
2#include "LibcMemoryBenchmark.h"
3#include "MemorySizeDistributions.h"
4#include "benchmark/benchmark.h"
5#include "llvm/ADT/ArrayRef.h"
6#include "llvm/ADT/Twine.h"
7#include <chrono>
8#include <cstdint>
9#include <random>
10#include <vector>
11
12using llvm::Align;
13using llvm::ArrayRef;
14using llvm::Twine;
15using llvm::libc_benchmarks::BzeroConfiguration;
16using llvm::libc_benchmarks::ComparisonSetup;
17using llvm::libc_benchmarks::CopySetup;
18using llvm::libc_benchmarks::MemcmpOrBcmpConfiguration;
19using llvm::libc_benchmarks::MemcpyConfiguration;
20using llvm::libc_benchmarks::MemmoveConfiguration;
21using llvm::libc_benchmarks::MemorySizeDistribution;
22using llvm::libc_benchmarks::MemsetConfiguration;
23using llvm::libc_benchmarks::MoveSetup;
24using llvm::libc_benchmarks::OffsetDistribution;
25using llvm::libc_benchmarks::SetSetup;
26
27// Alignment to use for when accessing the buffers.
28static constexpr Align kBenchmarkAlignment = Align::Constant<1>();
29
30static std::mt19937_64 &getGenerator() {
31static std::mt19937_64 Generator(
32std::chrono::system_clock::now().time_since_epoch().count());
33return Generator;
34}
35
36template <typename SetupType, typename ConfigurationType> struct Runner {
37Runner(benchmark::State &S, llvm::ArrayRef<ConfigurationType> Configurations)
38: State(S), Distribution(SetupType::getDistributions()[State.range(0)]),
39Probabilities(Distribution.Probabilities),
40SizeSampler(Probabilities.begin(), Probabilities.end()),
41OffsetSampler(Setup.BufferSize, Probabilities.size() - 1,
42kBenchmarkAlignment),
43Configuration(Configurations[State.range(1)]) {
44for (auto &P : Setup.Parameters) {
45P.OffsetBytes = OffsetSampler(getGenerator());
46P.SizeBytes = SizeSampler(getGenerator());
47Setup.checkValid(P);
48}
49}
50
51~Runner() {
52const size_t TotalBytes =
53(State.iterations() * Setup.getBatchBytes()) / Setup.BatchSize;
54State.SetBytesProcessed(TotalBytes);
55State.SetItemsProcessed(State.iterations());
56State.SetLabel((Twine(Configuration.Name) + "," + Distribution.Name).str());
57State.counters["bytes_per_cycle"] = benchmark::Counter(
58TotalBytes / benchmark::CPUInfo::Get().cycles_per_second,
59benchmark::Counter::kIsRate);
60}
61
62inline void runBatch() {
63for (const auto &P : Setup.Parameters)
64benchmark::DoNotOptimize(Setup.Call(P, Configuration.Function));
65}
66
67size_t getBatchSize() const { return Setup.BatchSize; }
68
69private:
70SetupType Setup;
71benchmark::State &State;
72MemorySizeDistribution Distribution;
73ArrayRef<double> Probabilities;
74std::discrete_distribution<unsigned> SizeSampler;
75OffsetDistribution OffsetSampler;
76ConfigurationType Configuration;
77};
78
79#define BENCHMARK_MEMORY_FUNCTION(BM_NAME, SETUP, CONFIGURATION_TYPE, \
80CONFIGURATION_ARRAY_REF) \
81void BM_NAME(benchmark::State &State) { \
82Runner<SETUP, CONFIGURATION_TYPE> Setup(State, CONFIGURATION_ARRAY_REF); \
83const size_t BatchSize = Setup.getBatchSize(); \
84while (State.KeepRunningBatch(BatchSize)) \
85Setup.runBatch(); \
86} \
87BENCHMARK(BM_NAME)->Apply([](benchmark::internal::Benchmark *benchmark) { \
88const int64_t DistributionSize = SETUP::getDistributions().size(); \
89const int64_t ConfigurationSize = CONFIGURATION_ARRAY_REF.size(); \
90for (int64_t DistIndex = 0; DistIndex < DistributionSize; ++DistIndex) \
91for (int64_t ConfIndex = 0; ConfIndex < ConfigurationSize; ++ConfIndex) \
92benchmark->Args({DistIndex, ConfIndex}); \
93})
94
95extern llvm::ArrayRef<MemcpyConfiguration> getMemcpyConfigurations();
96BENCHMARK_MEMORY_FUNCTION(BM_Memcpy, CopySetup, MemcpyConfiguration,
97getMemcpyConfigurations());
98
99extern llvm::ArrayRef<MemmoveConfiguration> getMemmoveConfigurations();
100BENCHMARK_MEMORY_FUNCTION(BM_Memmove, MoveSetup, MemmoveConfiguration,
101getMemmoveConfigurations());
102
103extern llvm::ArrayRef<MemcmpOrBcmpConfiguration> getMemcmpConfigurations();
104BENCHMARK_MEMORY_FUNCTION(BM_Memcmp, ComparisonSetup, MemcmpOrBcmpConfiguration,
105getMemcmpConfigurations());
106
107extern llvm::ArrayRef<MemcmpOrBcmpConfiguration> getBcmpConfigurations();
108BENCHMARK_MEMORY_FUNCTION(BM_Bcmp, ComparisonSetup, MemcmpOrBcmpConfiguration,
109getBcmpConfigurations());
110
111extern llvm::ArrayRef<MemsetConfiguration> getMemsetConfigurations();
112BENCHMARK_MEMORY_FUNCTION(BM_Memset, SetSetup, MemsetConfiguration,
113getMemsetConfigurations());
114
115extern llvm::ArrayRef<BzeroConfiguration> getBzeroConfigurations();
116BENCHMARK_MEMORY_FUNCTION(BM_Bzero, SetSetup, BzeroConfiguration,
117getBzeroConfigurations());
118