Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

boomanaiden154
Copy link
Contributor

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.

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.
@llvmbot
Copy link
Member

llvmbot commented Feb 9, 2024

@llvm/pr-subscribers-tools-llvm-exegesis

Author: Aiden Grossman (boomanaiden154)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/81219.diff

3 Files Affected:

  • (modified) llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp (+41-41)
  • (modified) llvm/tools/llvm-exegesis/lib/BenchmarkResult.h (+3)
  • (modified) llvm/tools/llvm-exegesis/lib/LatencyBenchmarkRunner.cpp (+9-3)
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;

Copy link

github-actions bot commented Feb 9, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@boomanaiden154 boomanaiden154 force-pushed the exegesis-debug-print-latencies branch from 6d41d48 to 461feb5 Compare February 19, 2024 09:38
@boomanaiden154 boomanaiden154 merged commit 93db5b7 into llvm:main Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants