From b77172ce2f42769631f24164a80c6b4453ebe42d Mon Sep 17 00:00:00 2001 From: spupyrev Date: Mon, 16 Oct 2017 16:53:50 -0700 Subject: [PATCH] updating cache metrics Summary: This is a replacement of a previous diff. The implemented metric ('graph distance') is not very useful at the moment but I plan to add more relevant metrics in the subsequent diff. This diff fixes some obvious problems and moves the call of CalcMetrics::printAll to the right place. (cherry picked from FBD6072312) --- bolt/CMakeLists.txt | 2 +- ...{CalcCacheMetrics.cpp => CacheMetrics.cpp} | 127 ++++++++---------- bolt/CacheMetrics.h | 27 ++++ bolt/CalcCacheMetrics.h | 27 ---- bolt/RewriteInstance.cpp | 23 ++-- 5 files changed, 90 insertions(+), 116 deletions(-) rename bolt/{CalcCacheMetrics.cpp => CacheMetrics.cpp} (53%) create mode 100644 bolt/CacheMetrics.h delete mode 100644 bolt/CalcCacheMetrics.h diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt index 1194d7da67a3..dd8a44975134 100644 --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -64,7 +64,7 @@ add_llvm_tool(llvm-bolt BinaryContext.cpp BinaryFunction.cpp BinaryPassManager.cpp - CalcCacheMetrics.cpp + CacheMetrics.cpp DataAggregator.cpp DataReader.cpp DebugData.cpp diff --git a/bolt/CalcCacheMetrics.cpp b/bolt/CacheMetrics.cpp similarity index 53% rename from bolt/CalcCacheMetrics.cpp rename to bolt/CacheMetrics.cpp index 166b3c3b7dd4..4e5b08fe2729 100644 --- a/bolt/CalcCacheMetrics.cpp +++ b/bolt/CacheMetrics.cpp @@ -1,4 +1,4 @@ -//===------ CalcCacheMetrics.cpp - Calculate metrics of cache lines -------===// +//===------ CacheMetrics.cpp - Calculate metrics for instruction cache ----===// // // Functions to show metrics of cache lines // @@ -7,31 +7,12 @@ // //===----------------------------------------------------------------------===// - -#include "BinaryBasicBlock.h" -#include "BinaryContext.h" -#include "BinaryFunction.h" -#include "BinaryPassManager.h" -#include "CalcCacheMetrics.h" -#include "Exceptions.h" -#include "RewriteInstance.h" -#include "llvm/MC/MCAsmLayout.h" -#include "llvm/MC/MCObjectStreamer.h" -#include "llvm/MC/MCSectionELF.h" -#include +#include "CacheMetrics.h" using namespace llvm; -using namespace object; using namespace bolt; using Traversal = std::vector; -namespace opts { - -extern cl::OptionCategory BoltOptCategory; - -} // namespace opts - - namespace { /// Initialize and return a position map for binary basic blocks. @@ -47,10 +28,8 @@ getPositionMap(const BinaryFunction &Function) { return DistMap; } -/// Initialize and return a vector of traversals for a given function and its -/// entry point -std::vector getTraversals(const BinaryFunction &Function, - BinaryBasicBlock *EntryBB) { +/// Initialize and return a vector of traversals for a given entry block +std::vector getTraversals(BinaryBasicBlock *EntryBB) { std::vector AllTraversals; std::stack> Stack; Stack.push(std::make_pair(EntryBB, Traversal())); @@ -105,10 +84,6 @@ std::vector getTraversals(const BinaryFunction &Function, double getTraversalLength(std::unordered_map &DistMap, Traversal const &Path) { - if (Path.size() <= 1) { - return 0.0; - } - double Length = 0.0; BinaryBasicBlock *PrevBB = Path.front(); for (auto BBI = std::next(Path.begin()); BBI != Path.end(); ++BBI) { @@ -119,56 +94,62 @@ getTraversalLength(std::unordered_map &DistMap, return Length; } -/// Helper function of calcGraphDistance to go through the call traversals of -/// certain function and to calculate and record the length of each -/// traversal. -void graphDistHelper(std::vector &AllTraversals, - const BinaryFunction &Function, - std::unordered_map &TraversalMap, - uint64_t &TraversalCount) { - auto DistMap = getPositionMap(Function); - - for (auto const &Path : AllTraversals) { - TraversalMap[++TraversalCount] = getTraversalLength(DistMap, Path); - } -} -} - -void CalcCacheMetrics::calcGraphDistance( - const std::map &BinaryFunctions) { - - double TotalFuncValue = 0; - uint64_t FuncCount = 0; - for (auto &BFI : BinaryFunctions) { - auto &Function = BFI.second; +/// Calculate average number of call distance for every graph traversal +double calcGraphDistance(const std::vector &BinaryFunctions) { + double TotalTraversalLength = 0; + double NumTraversals = 0; + for (auto BF : BinaryFunctions) { // Only consider functions which are known to be executed - if (Function.getKnownExecutionCount() == 0) + if (BF->getKnownExecutionCount() == 0) continue; - std::unordered_map TraversalMap; - uint64_t TraversalCount = 0; - for (auto *BB : Function.layout()) { + for (auto BB : BF->layout()) { if (BB->isEntryPoint()) { - auto AllTraversals = getTraversals(Function, BB); - graphDistHelper(AllTraversals, Function, TraversalMap, TraversalCount); + auto AllTraversals = getTraversals(BB); + auto DistMap = getPositionMap(*BF); + for (auto const &Path : AllTraversals) { + // Ignore short traversals + if (Path.size() <= 1) + continue; + TotalTraversalLength += getTraversalLength(DistMap, Path); + NumTraversals++; + } } } - - double TotalValue = 0; - for (auto const &Entry : TraversalMap) { - TotalValue += Entry.second; - } - - double AverageValue = - TraversalMap.empty() ? 0 : (TotalValue * 1.0 / TraversalMap.size()); - TotalFuncValue += AverageValue; - FuncCount += TraversalMap.empty() ? 0 : 1; } - outs() << format(" Sum of averages of traversal distance for all " - "functions is: %.2f\n", - TotalFuncValue) - << format(" There are %u functions in total\n", FuncCount) - << format(" On average, every traversal is %.2f long\n\n", - TotalFuncValue / FuncCount); + return TotalTraversalLength / NumTraversals; +} + +} + +void CacheMetrics::printAll( + const std::vector &BinaryFunctions) { + + size_t NumFunctions = 0; + size_t NumHotFunctions = 0; + size_t NumBlocks = 0; + size_t NumHotBlocks = 0; + + for (auto BF : BinaryFunctions) { + NumFunctions++; + if (BF->getKnownExecutionCount() > 0) + NumHotFunctions++; + for (auto BB : BF->layout()) { + NumBlocks++; + if (BB->getKnownExecutionCount() > 0) + NumHotBlocks++; + } + } + + outs() << format(" There are %zu functions;", NumFunctions) + << format(" %zu (%.2lf%%) have non-empty execution count\n", + NumHotFunctions, 100.0 * NumHotFunctions / NumFunctions); + outs() << format(" There are %zu basic blocks;", NumBlocks) + << format(" %zu (%.2lf%%) have non-empty execution count\n", + NumHotBlocks, 100.0 * NumHotBlocks / NumBlocks); + + const auto GraphDistance = calcGraphDistance(BinaryFunctions); + outs() << " An average length of graph traversal is " + << format("%.2lf\n", GraphDistance); } diff --git a/bolt/CacheMetrics.h b/bolt/CacheMetrics.h new file mode 100644 index 000000000000..e4ca3abc34f9 --- /dev/null +++ b/bolt/CacheMetrics.h @@ -0,0 +1,27 @@ +//===- CacheMetrics.h - Interface for instruction cache evaluation --===// +// +// Functions to show metrics of cache lines +// +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_BOLT_CACHEMETRICS_H +#define LLVM_TOOLS_LLVM_BOLT_CACHEMETRICS_H + +#include "BinaryFunction.h" +#include + +namespace llvm { +namespace bolt { +namespace CacheMetrics { + +/// Calculate and print various metrics related to instruction cache performance +void printAll(const std::vector &BinaryFunctions); + +} // namespace CacheMetrics +} // namespace bolt +} // namespace llvm + +#endif //LLVM_CACHEMETRICS_H diff --git a/bolt/CalcCacheMetrics.h b/bolt/CalcCacheMetrics.h deleted file mode 100644 index 07ca4551e28f..000000000000 --- a/bolt/CalcCacheMetrics.h +++ /dev/null @@ -1,27 +0,0 @@ -//===- CalcCacheMetrics.h - Interface for metrics printing of cache lines --===// -// -// Functions to show metrics of cache lines -// -// -//===----------------------------------------------------------------------===// -// -//===----------------------------------------------------------------------===// - - -#ifndef LLVM_CALCCACHEMETRICS_H -#define LLVM_CALCCACHEMETRICS_H - -#include "BinaryFunction.h" -#include - -using namespace llvm; -using namespace object; -using namespace bolt; - -namespace CalcCacheMetrics { -/// Calculate average number of call distance for every graph traversal. -void calcGraphDistance( - const std::map &BinaryFunctions); -} - -#endif //LLVM_CALCCACHEMETRICS_H diff --git a/bolt/RewriteInstance.cpp b/bolt/RewriteInstance.cpp index dbdb521bd149..3274f213d908 100644 --- a/bolt/RewriteInstance.cpp +++ b/bolt/RewriteInstance.cpp @@ -14,7 +14,7 @@ #include "BinaryContext.h" #include "BinaryFunction.h" #include "BinaryPassManager.h" -#include "CalcCacheMetrics.h" +#include "CacheMetrics.h" #include "DataAggregator.h" #include "DataReader.h" #include "Exceptions.h" @@ -79,8 +79,8 @@ extern cl::opt JumpTables; extern cl::opt ReorderFunctions; static cl::opt -CalcCacheMetrics("calc-cache-metrics", - cl::desc("calculate metrics of cache lines"), +PrintCacheMetrics("print-cache-metrics", + cl::desc("calculate and print various metrics for instruction cache"), cl::init(false), cl::ZeroOrMore, cl::cat(BoltOptCategory)); @@ -920,12 +920,6 @@ void RewriteInstance::run() { executeRewritePass(LargeFunctions); } - if (opts::CalcCacheMetrics) { - outs() << "\nBOLT-INFO: After Optimization CFG Graph Statistics: Jump " - "Distance \n\n"; - CalcCacheMetrics::calcGraphDistance(BinaryFunctions); - } - if (opts::UpdateDebugSections) updateDebugInfo(); @@ -2096,12 +2090,6 @@ void RewriteInstance::disassembleFunctions() { } } } - - if (opts::CalcCacheMetrics) { - outs() << "\nBOLT-INFO: Before Optimization CFG Graph Statistics: Jump " - "Distance \n\n"; - CalcCacheMetrics::calcGraphDistance(BinaryFunctions); - } } void RewriteInstance::runOptimizationPasses() { @@ -2424,6 +2412,11 @@ void RewriteInstance::emitFunctions() { OLT.emitAndFinalize(ObjectsHandle); + if (opts::PrintCacheMetrics) { + outs() << "BOLT-INFO: cache metrics after optimization\n"; + CacheMetrics::printAll(SortedFunctions); + } + if (opts::KeepTmp) TempOut->keep(); }