[llvm] [llvm-exegesis] Add debug option to print per-measurement values (PR #81219)

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 19:31:32 PST 2024


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/81219

>From 89aee78a9c7819edb12e14a7414ab33515dbe9b0 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Thu, 8 Feb 2024 19:22:31 -0800
Subject: [PATCH 1/2] [llvm-exegesis] Add debug option to print per-measurement
 values

This patch adds a debug option to print per measurement latency and
validation counter values. This makes it easier to debug certain
transient issues that can be hard to spot just using the summary view
at the end.

I've hacked print statements into this part of the code base enough
times for debugging various things that I think it makes sense to be a
proper debug macro.
---
 .../llvm-exegesis/lib/BenchmarkResult.cpp     | 82 +++++++++----------
 .../tools/llvm-exegesis/lib/BenchmarkResult.h |  3 +
 .../lib/LatencyBenchmarkRunner.cpp            | 12 ++-
 3 files changed, 53 insertions(+), 44 deletions(-)

diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index c193a8e5027713..0d6317f06054f7 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -193,51 +193,12 @@ template <> struct SequenceElementTraits<exegesis::BenchmarkMeasure> {
   static const bool flow = false;
 };
 
-const char *validationEventToString(exegesis::ValidationEvent VE) {
-  switch (VE) {
-  case exegesis::ValidationEvent::InstructionRetired:
-    return "instructions-retired";
-  case exegesis::ValidationEvent::L1DCacheLoadMiss:
-    return "l1d-cache-load-misses";
-  case exegesis::ValidationEvent::L1DCacheStoreMiss:
-    return "l1d-cache-store-misses";
-  case exegesis::ValidationEvent::L1ICacheLoadMiss:
-    return "l1i-cache-load-misses";
-  case exegesis::ValidationEvent::DataTLBLoadMiss:
-    return "data-tlb-load-misses";
-  case exegesis::ValidationEvent::DataTLBStoreMiss:
-    return "data-tlb-store-misses";
-  case exegesis::ValidationEvent::InstructionTLBLoadMiss:
-    return "instruction-tlb-load-misses";
-  }
-  llvm_unreachable("Unhandled exegesis::ValidationEvent enum");
-}
-
-Expected<exegesis::ValidationEvent> stringToValidationEvent(StringRef Input) {
-  if (Input == "instructions-retired")
-    return exegesis::ValidationEvent::InstructionRetired;
-  else if (Input == "l1d-cache-load-misses")
-    return exegesis::ValidationEvent::L1DCacheLoadMiss;
-  else if (Input == "l1d-cache-store-misses")
-    return exegesis::ValidationEvent::L1DCacheStoreMiss;
-  else if (Input == "l1i-cache-load-misses")
-    return exegesis::ValidationEvent::L1ICacheLoadMiss;
-  else if (Input == "data-tlb-load-misses")
-    return exegesis::ValidationEvent::DataTLBLoadMiss;
-  else if (Input == "data-tlb-store-misses")
-    return exegesis::ValidationEvent::DataTLBStoreMiss;
-  else if (Input == "instruction-tlb-load-misses")
-    return exegesis::ValidationEvent::InstructionTLBLoadMiss;
-  else
-    return make_error<StringError>("Invalid validation event string",
-                                   errc::invalid_argument);
-}
 
 template <>
 struct CustomMappingTraits<std::map<exegesis::ValidationEvent, int64_t>> {
   static void inputOne(IO &Io, StringRef KeyStr,
                        std::map<exegesis::ValidationEvent, int64_t> &VI) {
-    Expected<exegesis::ValidationEvent> Key = stringToValidationEvent(KeyStr);
+    Expected<exegesis::ValidationEvent> Key = exegesis::stringToValidationEvent(KeyStr);
     if (!Key) {
       Io.setError("Key is not a valid validation event");
       return;
@@ -247,7 +208,7 @@ struct CustomMappingTraits<std::map<exegesis::ValidationEvent, int64_t>> {
 
   static void output(IO &Io, std::map<exegesis::ValidationEvent, int64_t> &VI) {
     for (auto &IndividualVI : VI) {
-      Io.mapRequired(validationEventToString(IndividualVI.first),
+      Io.mapRequired(exegesis::validationEventToString(IndividualVI.first),
                      IndividualVI.second);
     }
   }
@@ -480,6 +441,45 @@ bool operator==(const BenchmarkMeasure &A, const BenchmarkMeasure &B) {
          std::tie(B.Key, B.PerInstructionValue, B.PerSnippetValue);
 }
 
+const char *validationEventToString(ValidationEvent VE) {
+  switch (VE) {
+  case exegesis::ValidationEvent::InstructionRetired:
+    return "instructions-retired";
+  case exegesis::ValidationEvent::L1DCacheLoadMiss:
+    return "l1d-cache-load-misses";
+  case exegesis::ValidationEvent::L1DCacheStoreMiss:
+    return "l1d-cache-store-misses";
+  case exegesis::ValidationEvent::L1ICacheLoadMiss:
+    return "l1i-cache-load-misses";
+  case exegesis::ValidationEvent::DataTLBLoadMiss:
+    return "data-tlb-load-misses";
+  case exegesis::ValidationEvent::DataTLBStoreMiss:
+    return "data-tlb-store-misses";
+  case exegesis::ValidationEvent::InstructionTLBLoadMiss:
+    return "instruction-tlb-load-misses";
+  }
+  llvm_unreachable("Unhandled exegesis::ValidationEvent enum");
+}
+
+Expected<ValidationEvent> stringToValidationEvent(StringRef Input) {
+  if (Input == "instructions-retired")
+    return exegesis::ValidationEvent::InstructionRetired;
+  else if (Input == "l1d-cache-load-misses")
+    return exegesis::ValidationEvent::L1DCacheLoadMiss;
+  else if (Input == "l1d-cache-store-misses")
+    return exegesis::ValidationEvent::L1DCacheStoreMiss;
+  else if (Input == "l1i-cache-load-misses")
+    return exegesis::ValidationEvent::L1ICacheLoadMiss;
+  else if (Input == "data-tlb-load-misses")
+    return exegesis::ValidationEvent::DataTLBLoadMiss;
+  else if (Input == "data-tlb-store-misses")
+    return exegesis::ValidationEvent::DataTLBStoreMiss;
+  else if (Input == "instruction-tlb-load-misses")
+    return exegesis::ValidationEvent::InstructionTLBLoadMiss;
+  else
+    return make_error<StringError>("Invalid validation event string",
+                                   errc::invalid_argument);
+}
 
 } // namespace exegesis
 } // namespace llvm
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
index 43f03ff5413388..1f16314986000e 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
@@ -42,6 +42,9 @@ enum ValidationEvent {
   InstructionTLBLoadMiss
 };
 
+const char *validationEventToString(exegesis::ValidationEvent VE);
+Expected<ValidationEvent> stringToValidationEvent(StringRef Input);
+
 enum class BenchmarkPhaseSelectorE {
   PrepareSnippet,
   PrepareAndAssembleSnippet,
diff --git a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
index 633740494e33e7..cb1cd426e995e7 100644
--- a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
@@ -15,6 +15,8 @@
 #include <algorithm>
 #include <cmath>
 
+#define DEBUG_TYPE "exegesis-latency-benchmarkrunner"
+
 namespace llvm {
 namespace exegesis {
 
@@ -91,9 +93,10 @@ Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
     if (!ExpectedCounterValues)
       return ExpectedCounterValues.takeError();
     ValuesCount = ExpectedCounterValues.get().size();
-    if (ValuesCount == 1)
+    if (ValuesCount == 1) {
+      LLVM_DEBUG(dbgs() << "Latency value: " << ExpectedCounterValues.get()[0] << "\n");
       AccumulatedValues.push_back(ExpectedCounterValues.get()[0]);
-    else {
+    } else {
       // We'll keep the reading with lowest variance (ie., most stable)
       double Variance = computeVariance(*ExpectedCounterValues);
       if (MinVariance > Variance) {
@@ -102,8 +105,11 @@ Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
       }
     }
 
-    for (size_t I = 0; I < ValCounterValues.size(); ++I)
+    for (size_t I = 0; I < ValCounterValues.size(); ++I) {
+      LLVM_DEBUG(dbgs() << validationEventToString(ValidationCounters[I])
+                        << ": " << IterationValCounterValues[I] << "\n");
       ValCounterValues[I] += IterationValCounterValues[I];
+    }
   }
 
   std::map<ValidationEvent, int64_t> ValidationInfo;

>From e622234a9a369b02647f7911930b266426d6a8be Mon Sep 17 00:00:00 2001
From: Aiden Grossman <agrossman154 at yahoo.com>
Date: Thu, 8 Feb 2024 19:31:23 -0800
Subject: [PATCH 2/2] Fix formatting

---
 llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp        | 4 ++--
 llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
index 0d6317f06054f7..8aace51161007e 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
@@ -193,12 +193,12 @@ template <> struct SequenceElementTraits<exegesis::BenchmarkMeasure> {
   static const bool flow = false;
 };
 
-
 template <>
 struct CustomMappingTraits<std::map<exegesis::ValidationEvent, int64_t>> {
   static void inputOne(IO &Io, StringRef KeyStr,
                        std::map<exegesis::ValidationEvent, int64_t> &VI) {
-    Expected<exegesis::ValidationEvent> Key = exegesis::stringToValidationEvent(KeyStr);
+    Expected<exegesis::ValidationEvent> Key =
+        exegesis::stringToValidationEvent(KeyStr);
     if (!Key) {
       Io.setError("Key is not a valid validation event");
       return;
diff --git a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
index cb1cd426e995e7..a9917a29cce24d 100644
--- a/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp
@@ -94,7 +94,8 @@ Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
       return ExpectedCounterValues.takeError();
     ValuesCount = ExpectedCounterValues.get().size();
     if (ValuesCount == 1) {
-      LLVM_DEBUG(dbgs() << "Latency value: " << ExpectedCounterValues.get()[0] << "\n");
+      LLVM_DEBUG(dbgs() << "Latency value: " << ExpectedCounterValues.get()[0]
+                        << "\n");
       AccumulatedValues.push_back(ExpectedCounterValues.get()[0]);
     } else {
       // We'll keep the reading with lowest variance (ie., most stable)



More information about the llvm-commits mailing list