aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-exegesis/lib/Analysis.cpp
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2019-03-29 11:36:08 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2019-03-29 11:36:08 +0000
commitb8fb15d4122b04d620c1d4a89449b6eba2f4b0c0 (patch)
treea4583c4fd8f1064a6e2b3b5760ff74332396adc8 /llvm/tools/llvm-exegesis/lib/Analysis.cpp
parentaeaf7fcddeefe733c87f69d88265f9e27540e5ec (diff)
downloadllvm-b8fb15d4122b04d620c1d4a89449b6eba2f4b0c0.zip
llvm-b8fb15d4122b04d620c1d4a89449b6eba2f4b0c0.tar.gz
llvm-b8fb15d4122b04d620c1d4a89449b6eba2f4b0c0.tar.bz2
[NFC][llvm-exegesis] Refactor Analysis::SchedClassCluster::measurementsMatch()
Summary: The diff looks scary but it really isn't: 1. I moved the check for the number of measurements into `SchedClassClusterCentroid::validate()` 2. While there, added a check that we can only have a single inverse throughput measurement. I missed that when adding it initially. 3. In `Analysis::SchedClassCluster::measurementsMatch()` is called with the current LLVM values from schedule class and the values from Centroid. 3.1. The values from centroid we can already get from `SchedClassClusterCentroid::getAsPoint()`. This isn't 100% a NFC, because previously for inverse throughput we used `min()`. I have asked whether i have done that correctly in https://reviews.llvm.org/D57647?id=184939#inline-510384 but did not hear back. I think `avg()` should be used too, thus it is a fix. 3.2. Finally, refactor the computation of the LLVM-specified values into `Analysis::SchedClassCluster::getSchedClassPoint()` I will need that function for [[ https://bugs.llvm.org/show_bug.cgi?id=41275 | PR41275 ]] Reviewers: courbet, gchatelet Reviewed By: courbet Subscribers: tschuett, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59951 llvm-svn: 357245
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/Analysis.cpp')
-rw-r--r--llvm/tools/llvm-exegesis/lib/Analysis.cpp82
1 files changed, 51 insertions, 31 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
index 9281744..632ba81 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -460,36 +460,33 @@ static unsigned findProcResIdx(const llvm::MCSubtargetInfo &STI,
return 0;
}
-bool Analysis::SchedClassCluster::measurementsMatch(
- const llvm::MCSubtargetInfo &STI, const ResolvedSchedClass &RSC,
- const InstructionBenchmarkClustering &Clustering,
- const double AnalysisInconsistencyEpsilonSquared_) const {
- ArrayRef<PerInstructionStats> Representative = Centroid.getStats();
+std::vector<BenchmarkMeasure> Analysis::SchedClassCluster::getSchedClassPoint(
+ InstructionBenchmark::ModeE Mode, const llvm::MCSubtargetInfo &STI,
+ const ResolvedSchedClass &RSC,
+ ArrayRef<PerInstructionStats> Representative) const {
const size_t NumMeasurements = Representative.size();
- std::vector<BenchmarkMeasure> ClusterCenterPoint(NumMeasurements);
+
std::vector<BenchmarkMeasure> SchedClassPoint(NumMeasurements);
- // Latency case.
- assert(!Clustering.getPoints().empty());
- const InstructionBenchmark::ModeE Mode = Clustering.getPoints()[0].Mode;
+
if (Mode == InstructionBenchmark::Latency) {
- if (NumMeasurements != 1) {
- llvm::errs()
- << "invalid number of measurements in latency mode: expected 1, got "
- << NumMeasurements << "\n";
- return false;
- }
+ assert(NumMeasurements == 1 && "Latency is a single measure.");
+ BenchmarkMeasure &LatencyMeasure = SchedClassPoint[0];
+
// Find the latency.
- SchedClassPoint[0].PerInstructionValue = 0.0;
+ LatencyMeasure.PerInstructionValue = 0.0;
+
for (unsigned I = 0; I < RSC.SCDesc->NumWriteLatencyEntries; ++I) {
const llvm::MCWriteLatencyEntry *const WLE =
STI.getWriteLatencyEntry(RSC.SCDesc, I);
- SchedClassPoint[0].PerInstructionValue =
- std::max<double>(SchedClassPoint[0].PerInstructionValue, WLE->Cycles);
+ LatencyMeasure.PerInstructionValue =
+ std::max<double>(LatencyMeasure.PerInstructionValue, WLE->Cycles);
}
- ClusterCenterPoint[0].PerInstructionValue = Representative[0].avg();
} else if (Mode == InstructionBenchmark::Uops) {
- for (int I = 0, E = Representative.size(); I < E; ++I) {
- const auto Key = Representative[I].key();
+ for (const auto &I : llvm::zip(SchedClassPoint, Representative)) {
+ BenchmarkMeasure &Measure = std::get<0>(I);
+ const PerInstructionStats &Stats = std::get<1>(I);
+
+ StringRef Key = Stats.key();
uint16_t ProcResIdx = findProcResIdx(STI, Key);
if (ProcResIdx > 0) {
// Find the pressure on ProcResIdx `Key`.
@@ -499,30 +496,53 @@ bool Analysis::SchedClassCluster::measurementsMatch(
[ProcResIdx](const std::pair<uint16_t, float> &WPR) {
return WPR.first == ProcResIdx;
});
- SchedClassPoint[I].PerInstructionValue =
+ Measure.PerInstructionValue =
ProcResPressureIt == RSC.IdealizedProcResPressure.end()
? 0.0
: ProcResPressureIt->second;
} else if (Key == "NumMicroOps") {
- SchedClassPoint[I].PerInstructionValue = RSC.SCDesc->NumMicroOps;
+ Measure.PerInstructionValue = RSC.SCDesc->NumMicroOps;
} else {
llvm::errs() << "expected `key` to be either a ProcResIdx or a ProcRes "
"name, got "
<< Key << "\n";
- return false;
+ return {};
}
- ClusterCenterPoint[I].PerInstructionValue = Representative[I].avg();
}
} else if (Mode == InstructionBenchmark::InverseThroughput) {
- for (int I = 0, E = Representative.size(); I < E; ++I) {
- SchedClassPoint[I].PerInstructionValue =
- MCSchedModel::getReciprocalThroughput(STI, *RSC.SCDesc);
- ClusterCenterPoint[I].PerInstructionValue = Representative[I].min();
- }
+ assert(NumMeasurements == 1 && "Inverse Throughput is a single measure.");
+ BenchmarkMeasure &RThroughputMeasure = SchedClassPoint[0];
+
+ RThroughputMeasure.PerInstructionValue =
+ MCSchedModel::getReciprocalThroughput(STI, *RSC.SCDesc);
} else {
llvm_unreachable("unimplemented measurement matching mode");
- return false;
}
+
+ return SchedClassPoint;
+}
+
+bool Analysis::SchedClassCluster::measurementsMatch(
+ const llvm::MCSubtargetInfo &STI, const ResolvedSchedClass &RSC,
+ const InstructionBenchmarkClustering &Clustering,
+ const double AnalysisInconsistencyEpsilonSquared_) const {
+ assert(!Clustering.getPoints().empty());
+ const InstructionBenchmark::ModeE Mode = Clustering.getPoints()[0].Mode;
+
+ if (!Centroid.validate(Mode))
+ return false;
+
+ const std::vector<BenchmarkMeasure> ClusterCenterPoint =
+ Centroid.getAsPoint();
+
+ const std::vector<BenchmarkMeasure> SchedClassPoint =
+ getSchedClassPoint(Mode, STI, RSC, Centroid.getStats());
+ if (SchedClassPoint.empty())
+ return false; // In Uops mode validate() may not be enough.
+
+ assert(ClusterCenterPoint.size() == SchedClassPoint.size() &&
+ "Expected measured/sched data dimensions to match.");
+
return Clustering.isNeighbour(ClusterCenterPoint, SchedClassPoint,
AnalysisInconsistencyEpsilonSquared_);
}