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