147 lines · c
1//===-- BenchmarkRunner.h ---------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// Defines the abstract BenchmarkRunner class for measuring a certain execution11/// property of instructions (e.g. latency).12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H16#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H17 18#include "Assembler.h"19#include "BenchmarkCode.h"20#include "BenchmarkResult.h"21#include "LlvmState.h"22#include "MCInstrDescView.h"23#include "SnippetRepetitor.h"24#include "llvm/ADT/SmallVector.h"25#include "llvm/MC/MCInst.h"26#include "llvm/Support/Error.h"27#include <cstdlib>28#include <memory>29#include <vector>30 31namespace llvm {32namespace exegesis {33 34// Common code for all benchmark modes.35class BenchmarkRunner {36public:37 enum ExecutionModeE { InProcess, SubProcess };38 39 explicit BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,40 BenchmarkPhaseSelectorE BenchmarkPhaseSelector,41 ExecutionModeE ExecutionMode,42 ArrayRef<ValidationEvent> ValCounters);43 44 virtual ~BenchmarkRunner();45 46 class RunnableConfiguration {47 friend class BenchmarkRunner;48 49 public:50 ~RunnableConfiguration() = default;51 RunnableConfiguration(RunnableConfiguration &&) = default;52 53 RunnableConfiguration(const RunnableConfiguration &) = delete;54 RunnableConfiguration &operator=(RunnableConfiguration &&) = delete;55 RunnableConfiguration &operator=(const RunnableConfiguration &) = delete;56 57 private:58 RunnableConfiguration() = default;59 60 Benchmark BenchmarkResult;61 object::OwningBinary<object::ObjectFile> ObjectFile;62 };63 64 Expected<RunnableConfiguration>65 getRunnableConfiguration(const BenchmarkCode &Configuration,66 unsigned MinInstructions, unsigned LoopUnrollFactor,67 const SnippetRepetitor &Repetitor) const;68 69 std::pair<Error, Benchmark>70 runConfiguration(RunnableConfiguration &&RC,71 const std::optional<StringRef> &DumpFile,72 std::optional<int> BenchmarkProcessCPU) const;73 74 // Scratch space to run instructions that touch memory.75 struct ScratchSpace {76 static constexpr size_t kAlignment = 1024;77 static constexpr size_t kSize = 1 << 20; // 1MB.78 ScratchSpace()79 : UnalignedPtr(std::make_unique<char[]>(kSize + kAlignment)),80 AlignedPtr(81 UnalignedPtr.get() + kAlignment -82 (reinterpret_cast<intptr_t>(UnalignedPtr.get()) % kAlignment)) {}83 char *ptr() const { return AlignedPtr; }84 void clear() { std::memset(ptr(), 0, kSize); }85 86 private:87 const std::unique_ptr<char[]> UnalignedPtr;88 char *const AlignedPtr;89 };90 91 // A helper to measure counters while executing a function in a sandboxed92 // context.93 class FunctionExecutor {94 public:95 virtual ~FunctionExecutor();96 97 Expected<SmallVector<int64_t, 4>>98 runAndSample(const char *Counters,99 ArrayRef<const char *> ValidationCounters,100 SmallVectorImpl<int64_t> &ValidationCounterValues) const;101 102 protected:103 static void104 accumulateCounterValues(const SmallVectorImpl<int64_t> &NewValues,105 SmallVectorImpl<int64_t> *Result);106 virtual Expected<SmallVector<int64_t, 4>>107 runWithCounter(StringRef CounterName,108 ArrayRef<const char *> ValidationCounters,109 SmallVectorImpl<int64_t> &ValidationCounterValues) const = 0;110 };111 112protected:113 const LLVMState &State;114 const Benchmark::ModeE Mode;115 const BenchmarkPhaseSelectorE BenchmarkPhaseSelector;116 const ExecutionModeE ExecutionMode;117 118 SmallVector<ValidationEvent> ValidationCounters;119 120 Error121 getValidationCountersToRun(SmallVector<const char *> &ValCountersToRun) const;122 123private:124 virtual Expected<std::vector<BenchmarkMeasure>>125 runMeasurements(const FunctionExecutor &Executor) const = 0;126 127 Expected<SmallString<0>>128 assembleSnippet(const BenchmarkCode &BC, const SnippetRepetitor &Repetitor,129 unsigned MinInstructions, unsigned LoopBodySize,130 bool GenerateMemoryInstructions) const;131 132 Expected<std::string> writeObjectFile(StringRef Buffer,133 StringRef FileName) const;134 135 const std::unique_ptr<ScratchSpace> Scratch;136 137 Expected<std::unique_ptr<FunctionExecutor>>138 createFunctionExecutor(object::OwningBinary<object::ObjectFile> Obj,139 const BenchmarkKey &Key,140 std::optional<int> BenchmarkProcessCPU) const;141};142 143} // namespace exegesis144} // namespace llvm145 146#endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRUNNER_H147