Skip to content

Commit 92b81ae

Browse files
spupyrevmemfrob
authored andcommitted
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)
1 parent b472c30 commit 92b81ae

File tree

5 files changed

+88
-114
lines changed

5 files changed

+88
-114
lines changed

bolt/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ add_llvm_tool(llvm-bolt
6464
BinaryContext.cpp
6565
BinaryFunction.cpp
6666
BinaryPassManager.cpp
67-
CalcCacheMetrics.cpp
67+
CacheMetrics.cpp
6868
DataAggregator.cpp
6969
DataReader.cpp
7070
DebugData.cpp
Lines changed: 52 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===------ CalcCacheMetrics.cpp - Calculate metrics of cache lines -------===//
1+
//===------ CacheMetrics.cpp - Calculate metrics for instruction cache ----===//
22
//
33
// Functions to show metrics of cache lines
44
//
@@ -7,31 +7,12 @@
77
//
88
//===----------------------------------------------------------------------===//
99

10-
11-
#include "BinaryBasicBlock.h"
12-
#include "BinaryContext.h"
13-
#include "BinaryFunction.h"
14-
#include "BinaryPassManager.h"
15-
#include "CalcCacheMetrics.h"
16-
#include "Exceptions.h"
17-
#include "RewriteInstance.h"
18-
#include "llvm/MC/MCAsmLayout.h"
19-
#include "llvm/MC/MCObjectStreamer.h"
20-
#include "llvm/MC/MCSectionELF.h"
21-
#include <fstream>
10+
#include "CacheMetrics.h"
2211

2312
using namespace llvm;
24-
using namespace object;
2513
using namespace bolt;
2614
using Traversal = std::vector<BinaryBasicBlock *>;
2715

28-
namespace opts {
29-
30-
extern cl::OptionCategory BoltOptCategory;
31-
32-
} // namespace opts
33-
34-
3516
namespace {
3617

3718
/// Initialize and return a position map for binary basic blocks.
@@ -47,10 +28,8 @@ getPositionMap(const BinaryFunction &Function) {
4728
return DistMap;
4829
}
4930

50-
/// Initialize and return a vector of traversals for a given function and its
51-
/// entry point
52-
std::vector<Traversal> getTraversals(const BinaryFunction &Function,
53-
BinaryBasicBlock *EntryBB) {
31+
/// Initialize and return a vector of traversals for a given entry block
32+
std::vector<Traversal> getTraversals(BinaryBasicBlock *EntryBB) {
5433
std::vector<Traversal> AllTraversals;
5534
std::stack<std::pair<BinaryBasicBlock *, Traversal>> Stack;
5635
Stack.push(std::make_pair(EntryBB, Traversal()));
@@ -105,10 +84,6 @@ std::vector<Traversal> getTraversals(const BinaryFunction &Function,
10584
double
10685
getTraversalLength(std::unordered_map<BinaryBasicBlock *, double> &DistMap,
10786
Traversal const &Path) {
108-
if (Path.size() <= 1) {
109-
return 0.0;
110-
}
111-
11287
double Length = 0.0;
11388
BinaryBasicBlock *PrevBB = Path.front();
11489
for (auto BBI = std::next(Path.begin()); BBI != Path.end(); ++BBI) {
@@ -119,56 +94,62 @@ getTraversalLength(std::unordered_map<BinaryBasicBlock *, double> &DistMap,
11994
return Length;
12095
}
12196

122-
/// Helper function of calcGraphDistance to go through the call traversals of
123-
/// certain function and to calculate and record the length of each
124-
/// traversal.
125-
void graphDistHelper(std::vector<Traversal> &AllTraversals,
126-
const BinaryFunction &Function,
127-
std::unordered_map<uint64_t, double> &TraversalMap,
128-
uint64_t &TraversalCount) {
129-
auto DistMap = getPositionMap(Function);
130-
131-
for (auto const &Path : AllTraversals) {
132-
TraversalMap[++TraversalCount] = getTraversalLength(DistMap, Path);
133-
}
134-
}
135-
}
136-
137-
void CalcCacheMetrics::calcGraphDistance(
138-
const std::map<uint64_t, BinaryFunction> &BinaryFunctions) {
139-
140-
double TotalFuncValue = 0;
141-
uint64_t FuncCount = 0;
142-
for (auto &BFI : BinaryFunctions) {
143-
auto &Function = BFI.second;
97+
/// Calculate average number of call distance for every graph traversal
98+
double calcGraphDistance(const std::vector<BinaryFunction *> &BinaryFunctions) {
99+
double TotalTraversalLength = 0;
100+
double NumTraversals = 0;
101+
for (auto BF : BinaryFunctions) {
144102
// Only consider functions which are known to be executed
145-
if (Function.getKnownExecutionCount() == 0)
103+
if (BF->getKnownExecutionCount() == 0)
146104
continue;
147105

148-
std::unordered_map<uint64_t, double> TraversalMap;
149-
uint64_t TraversalCount = 0;
150-
for (auto *BB : Function.layout()) {
106+
for (auto BB : BF->layout()) {
151107
if (BB->isEntryPoint()) {
152-
auto AllTraversals = getTraversals(Function, BB);
153-
graphDistHelper(AllTraversals, Function, TraversalMap, TraversalCount);
108+
auto AllTraversals = getTraversals(BB);
109+
auto DistMap = getPositionMap(*BF);
110+
for (auto const &Path : AllTraversals) {
111+
// Ignore short traversals
112+
if (Path.size() <= 1)
113+
continue;
114+
TotalTraversalLength += getTraversalLength(DistMap, Path);
115+
NumTraversals++;
116+
}
154117
}
155118
}
119+
}
156120

157-
double TotalValue = 0;
158-
for (auto const &Entry : TraversalMap) {
159-
TotalValue += Entry.second;
160-
}
121+
return TotalTraversalLength / NumTraversals;
122+
}
161123

162-
double AverageValue =
163-
TraversalMap.empty() ? 0 : (TotalValue * 1.0 / TraversalMap.size());
164-
TotalFuncValue += AverageValue;
165-
FuncCount += TraversalMap.empty() ? 0 : 1;
124+
}
125+
126+
void CacheMetrics::printAll(
127+
const std::vector<BinaryFunction *> &BinaryFunctions) {
128+
129+
size_t NumFunctions = 0;
130+
size_t NumHotFunctions = 0;
131+
size_t NumBlocks = 0;
132+
size_t NumHotBlocks = 0;
133+
134+
for (auto BF : BinaryFunctions) {
135+
NumFunctions++;
136+
if (BF->getKnownExecutionCount() > 0)
137+
NumHotFunctions++;
138+
for (auto BB : BF->layout()) {
139+
NumBlocks++;
140+
if (BB->getKnownExecutionCount() > 0)
141+
NumHotBlocks++;
142+
}
166143
}
167144

168-
outs() << format(" Sum of averages of traversal distance for all "
169-
"functions is: %.2f\n",
170-
TotalFuncValue)
171-
<< format(" There are %u functions in total\n", FuncCount)
172-
<< format(" On average, every traversal is %.2f long\n\n",
173-
TotalFuncValue / FuncCount);
145+
outs() << format(" There are %zu functions;", NumFunctions)
146+
<< format(" %zu (%.2lf%%) have non-empty execution count\n",
147+
NumHotFunctions, 100.0 * NumHotFunctions / NumFunctions);
148+
outs() << format(" There are %zu basic blocks;", NumBlocks)
149+
<< format(" %zu (%.2lf%%) have non-empty execution count\n",
150+
NumHotBlocks, 100.0 * NumHotBlocks / NumBlocks);
151+
152+
const auto GraphDistance = calcGraphDistance(BinaryFunctions);
153+
outs() << " An average length of graph traversal is "
154+
<< format("%.2lf\n", GraphDistance);
174155
}

bolt/CacheMetrics.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===- CacheMetrics.h - Interface for instruction cache evaluation --===//
2+
//
3+
// Functions to show metrics of cache lines
4+
//
5+
//
6+
//===----------------------------------------------------------------------===//
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_TOOLS_LLVM_BOLT_CACHEMETRICS_H
11+
#define LLVM_TOOLS_LLVM_BOLT_CACHEMETRICS_H
12+
13+
#include "BinaryFunction.h"
14+
#include <map>
15+
16+
namespace llvm {
17+
namespace bolt {
18+
namespace CacheMetrics {
19+
20+
/// Calculate and print various metrics related to instruction cache performance
21+
void printAll(const std::vector<BinaryFunction *> &BinaryFunctions);
22+
23+
} // namespace CacheMetrics
24+
} // namespace bolt
25+
} // namespace llvm
26+
27+
#endif //LLVM_CACHEMETRICS_H

bolt/CalcCacheMetrics.h

Lines changed: 0 additions & 27 deletions
This file was deleted.

bolt/RewriteInstance.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "BinaryContext.h"
1515
#include "BinaryFunction.h"
1616
#include "BinaryPassManager.h"
17-
#include "CalcCacheMetrics.h"
17+
#include "CacheMetrics.h"
1818
#include "DataAggregator.h"
1919
#include "DataReader.h"
2020
#include "Exceptions.h"
@@ -79,8 +79,8 @@ extern cl::opt<JumpTableSupportLevel> JumpTables;
7979
extern cl::opt<BinaryFunction::ReorderType> ReorderFunctions;
8080

8181
static cl::opt<bool>
82-
CalcCacheMetrics("calc-cache-metrics",
83-
cl::desc("calculate metrics of cache lines"),
82+
PrintCacheMetrics("print-cache-metrics",
83+
cl::desc("calculate and print various metrics for instruction cache"),
8484
cl::init(false),
8585
cl::ZeroOrMore,
8686
cl::cat(BoltOptCategory));
@@ -920,12 +920,6 @@ void RewriteInstance::run() {
920920
executeRewritePass(LargeFunctions);
921921
}
922922

923-
if (opts::CalcCacheMetrics) {
924-
outs() << "\nBOLT-INFO: After Optimization CFG Graph Statistics: Jump "
925-
"Distance \n\n";
926-
CalcCacheMetrics::calcGraphDistance(BinaryFunctions);
927-
}
928-
929923
if (opts::UpdateDebugSections)
930924
updateDebugInfo();
931925

@@ -2096,12 +2090,6 @@ void RewriteInstance::disassembleFunctions() {
20962090
}
20972091
}
20982092
}
2099-
2100-
if (opts::CalcCacheMetrics) {
2101-
outs() << "\nBOLT-INFO: Before Optimization CFG Graph Statistics: Jump "
2102-
"Distance \n\n";
2103-
CalcCacheMetrics::calcGraphDistance(BinaryFunctions);
2104-
}
21052093
}
21062094

21072095
void RewriteInstance::runOptimizationPasses() {
@@ -2424,6 +2412,11 @@ void RewriteInstance::emitFunctions() {
24242412

24252413
OLT.emitAndFinalize(ObjectsHandle);
24262414

2415+
if (opts::PrintCacheMetrics) {
2416+
outs() << "BOLT-INFO: cache metrics after optimization\n";
2417+
CacheMetrics::printAll(SortedFunctions);
2418+
}
2419+
24272420
if (opts::KeepTmp)
24282421
TempOut->keep();
24292422
}

0 commit comments

Comments
 (0)