Skip to content

Commit fc791b6

Browse files
[llvm-exegesis] Add option to specify the number of measurement repetitions (#74276)
Currently, the llvm-exegesis LatencyBenchmarkRunner repeats the benchmark several times (currently 30) and then aggregates the result to deal with noise in the measurement process. With this patch, the number of repetitions to perform is made configurable rather than left as a static number. This allows for significantly faster execution in situations where someone is performing a task like experimenting with memory annotations where the exact cycle counts might not be useful, and also allows for increased precision when desired.
1 parent 3acbd38 commit fc791b6

File tree

5 files changed

+23
-8
lines changed

5 files changed

+23
-8
lines changed

llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ namespace exegesis {
2121
LatencyBenchmarkRunner::LatencyBenchmarkRunner(
2222
const LLVMState &State, Benchmark::ModeE Mode,
2323
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
24-
Benchmark::ResultAggregationModeE ResultAgg, ExecutionModeE ExecutionMode)
24+
Benchmark::ResultAggregationModeE ResultAgg, ExecutionModeE ExecutionMode,
25+
unsigned BenchmarkRepeatCount)
2526
: BenchmarkRunner(State, Mode, BenchmarkPhaseSelector, ExecutionMode) {
2627
assert((Mode == Benchmark::Latency || Mode == Benchmark::InverseThroughput) &&
2728
"invalid mode");
2829
ResultAggMode = ResultAgg;
30+
NumMeasurements = BenchmarkRepeatCount;
2931
}
3032

3133
LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
@@ -68,7 +70,6 @@ Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
6870
// Cycle measurements include some overhead from the kernel. Repeat the
6971
// measure several times and return the aggregated value, as specified by
7072
// ResultAggMode.
71-
constexpr const int NumMeasurements = 30;
7273
llvm::SmallVector<int64_t, 4> AccumulatedValues;
7374
double MinVariance = std::numeric_limits<double>::infinity();
7475
const char *CounterName = State.getPfmCounters().CycleCounter;

llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@ class LatencyBenchmarkRunner : public BenchmarkRunner {
2424
LatencyBenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
2525
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
2626
Benchmark::ResultAggregationModeE ResultAggMode,
27-
ExecutionModeE ExecutionMode);
27+
ExecutionModeE ExecutionMode,
28+
unsigned BenchmarkRepeatCount);
2829
~LatencyBenchmarkRunner() override;
2930

3031
private:
3132
Expected<std::vector<BenchmarkMeasure>>
3233
runMeasurements(const FunctionExecutor &Executor) const override;
3334

3435
Benchmark::ResultAggregationModeE ResultAggMode;
36+
unsigned NumMeasurements;
3537
};
3638
} // namespace exegesis
3739
} // namespace llvm

llvm/tools/llvm-exegesis/lib/Target.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ ExegesisTarget::createBenchmarkRunner(
7979
Benchmark::ModeE Mode, const LLVMState &State,
8080
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
8181
BenchmarkRunner::ExecutionModeE ExecutionMode,
82+
unsigned BenchmarkRepeatCount,
8283
Benchmark::ResultAggregationModeE ResultAggMode) const {
8384
PfmCountersInfo PfmCounters = State.getPfmCounters();
8485
switch (Mode) {
@@ -101,7 +102,8 @@ ExegesisTarget::createBenchmarkRunner(
101102
"the kernel for real event counts."));
102103
}
103104
return createLatencyBenchmarkRunner(State, Mode, BenchmarkPhaseSelector,
104-
ResultAggMode, ExecutionMode);
105+
ResultAggMode, ExecutionMode,
106+
BenchmarkRepeatCount);
105107
case Benchmark::Uops:
106108
if (BenchmarkPhaseSelector == BenchmarkPhaseSelectorE::Measure &&
107109
!PfmCounters.UopsCounter && !PfmCounters.IssueCounters)
@@ -130,9 +132,11 @@ std::unique_ptr<BenchmarkRunner> ExegesisTarget::createLatencyBenchmarkRunner(
130132
const LLVMState &State, Benchmark::ModeE Mode,
131133
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
132134
Benchmark::ResultAggregationModeE ResultAggMode,
133-
BenchmarkRunner::ExecutionModeE ExecutionMode) const {
135+
BenchmarkRunner::ExecutionModeE ExecutionMode,
136+
unsigned BenchmarkRepeatCount) const {
134137
return std::make_unique<LatencyBenchmarkRunner>(
135-
State, Mode, BenchmarkPhaseSelector, ResultAggMode, ExecutionMode);
138+
State, Mode, BenchmarkPhaseSelector, ResultAggMode, ExecutionMode,
139+
BenchmarkRepeatCount);
136140
}
137141

138142
std::unique_ptr<BenchmarkRunner> ExegesisTarget::createUopsBenchmarkRunner(

llvm/tools/llvm-exegesis/lib/Target.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ class ExegesisTarget {
262262
Benchmark::ModeE Mode, const LLVMState &State,
263263
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
264264
BenchmarkRunner::ExecutionModeE ExecutionMode,
265+
unsigned BenchmarkRepeatCount,
265266
Benchmark::ResultAggregationModeE ResultAggMode = Benchmark::Min) const;
266267

267268
// Returns the ExegesisTarget for the given triple or nullptr if the target
@@ -305,7 +306,8 @@ class ExegesisTarget {
305306
const LLVMState &State, Benchmark::ModeE Mode,
306307
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
307308
Benchmark::ResultAggregationModeE ResultAggMode,
308-
BenchmarkRunner::ExecutionModeE ExecutionMode) const;
309+
BenchmarkRunner::ExecutionModeE ExecutionMode,
310+
unsigned BenchmarkRepeatCount) const;
309311
std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
310312
const LLVMState &State, BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
311313
Benchmark::ResultAggregationModeE ResultAggMode,

llvm/tools/llvm-exegesis/llvm-exegesis.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ static cl::opt<BenchmarkRunner::ExecutionModeE> ExecutionMode(
262262
"allows for the use of memory annotations")),
263263
cl::init(BenchmarkRunner::ExecutionModeE::InProcess));
264264

265+
static cl::opt<unsigned> BenchmarkRepeatCount(
266+
"benchmark-repeat-count",
267+
cl::desc("The number of times to repeat measurements on the benchmark k "
268+
"before aggregating the results"),
269+
cl::cat(BenchmarkOptions), cl::init(30));
270+
265271
static ExitOnError ExitOnErr("llvm-exegesis error: ");
266272

267273
// Helper function that logs the error(s) and exits.
@@ -485,7 +491,7 @@ void benchmarkMain() {
485491
const std::unique_ptr<BenchmarkRunner> Runner =
486492
ExitOnErr(State.getExegesisTarget().createBenchmarkRunner(
487493
BenchmarkMode, State, BenchmarkPhaseSelector, ExecutionMode,
488-
ResultAggMode));
494+
BenchmarkRepeatCount, ResultAggMode));
489495
if (!Runner) {
490496
ExitWithError("cannot create benchmark runner");
491497
}

0 commit comments

Comments
 (0)