Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: src/IceTimerTree.cpp

Issue 610813002: Subzero: Rewrite the pass timing infrastructure. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make the optimized overlaps() implementation actually correct Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===- subzero/src/IceTimerTree.cpp - Pass timer defs ---------------------===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the TimerTree class, which tracks flat and
11 // cumulative execution time collection of call chains.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "IceDefs.h"
16 #include "IceTimerTree.h"
17
18 namespace Ice {
19
20 std::vector<IceString> TimerStack::IDs;
21
22 TimerStack::TimerStack(const IceString &TopLevelName)
23 : FirstTimestamp(timestamp()), LastTimestamp(FirstTimestamp),
24 StateChangeCount(0), StackTop(0) {
25 Nodes.resize(1); // Reserve Nodes[0] for the root node.
26 push(getTimerID(TopLevelName));
27 }
28
29 // Returns the unique timer ID for the given Name, creating a new ID
30 // if needed. For performance reasons, it's best to make only one
31 // call per Name and cache the result, e.g. via a static initializer.
32 TimerIdT TimerStack::getTimerID(const IceString &Name) {
33 TimerIdT Size = IDs.size();
34 for (TimerIdT i = 0; i < Size; ++i) {
35 if (IDs[i] == Name)
36 return i;
37 }
38 IDs.push_back(Name);
39 return Size;
40 }
41
42 // Pushes a new marker onto the timer stack.
43 void TimerStack::push(TimerIdT ID) {
44 update();
45 if (Nodes[StackTop].Children.size() <= ID)
46 Nodes[StackTop].Children.resize(ID + 1);
47 if (Nodes[StackTop].Children[ID] == 0) {
48 TTindex Size = Nodes.size();
49 Nodes[StackTop].Children[ID] = Size;
50 Nodes.resize(Size + 1);
51 Nodes[Size].Parent = StackTop;
52 Nodes[Size].Interior = ID;
53 }
54 StackTop = Nodes[StackTop].Children[ID];
55 }
56
57 // Pop the top marker from the timer stack. Validates via assert()
58 // that the expected marker is popped.
59 void TimerStack::pop(TimerIdT ID) {
60 update();
61 assert(StackTop);
62 assert(Nodes[StackTop].Parent < StackTop);
63 // Verify that the expected ID is being popped.
64 assert(Nodes[StackTop].Interior == ID);
65 (void)ID;
66 // Verify that the parent's child points to the current stack top.
67 assert(Nodes[Nodes[StackTop].Parent].Children[ID] == StackTop);
68 StackTop = Nodes[StackTop].Parent;
69 }
70
71 // At a state change (e.g. push or pop), updates the flat and
72 // cumulative timings for everything on the timer stack.
73 void TimerStack::update() {
74 ++StateChangeCount;
75 // Whenever the stack is about to change, we grab the time delta
76 // since the last change and add it to all active cumulative
77 // elements and to the flat element for the top of the stack.
78 double Current = timestamp();
79 double Delta = Current - LastTimestamp;
80 LastTimestamp = Current;
81 if (StackTop) {
82 TimerIdT Leaf = Nodes[StackTop].Interior;
83 if (Leaf >= LeafTimes.size())
84 LeafTimes.resize(Leaf + 1);
85 LeafTimes[Leaf] += Delta;
86 }
87 TTindex Prefix = StackTop;
88 while (Prefix) {
89 Nodes[Prefix].Time += Delta;
90 TTindex Next = Nodes[Prefix].Parent;
91 assert(Next < Prefix);
92 Prefix = Next;
93 }
94 }
95
96 namespace {
97
98 typedef std::multimap<double, IceString> DumpMapType;
99
100 // Dump the Map items in reverse order of their time contribution.
101 void dumpHelper(Ostream &Str, const DumpMapType &Map, double TotalTime) {
102 for (DumpMapType::const_reverse_iterator I = Map.rbegin(), E = Map.rend();
103 I != E; ++I) {
104 char buf[80];
105 snprintf(buf, llvm::array_lengthof(buf), " %10.6f (%4.1f%%): ", I->first,
106 I->first * 100 / TotalTime);
107 Str << buf << I->second << "\n";
108 }
109 }
110
111 } // end of anonymous namespace
112
113 void TimerStack::dump(Ostream &Str) {
114 update();
115 double TotalTime = LastTimestamp - FirstTimestamp;
116 assert(TotalTime);
117 Str << "Cumulative function times:\n";
118 DumpMapType CumulativeMap;
119 for (TTindex i = 1; i < Nodes.size(); ++i) {
120 TTindex Prefix = i;
121 IceString Suffix = "";
122 while (Prefix) {
123 if (Suffix.empty())
124 Suffix = IDs[Nodes[Prefix].Interior];
125 else
126 Suffix = IDs[Nodes[Prefix].Interior] + "." + Suffix;
127 assert(Nodes[Prefix].Parent < Prefix);
128 Prefix = Nodes[Prefix].Parent;
129 }
130 CumulativeMap.insert(std::make_pair(Nodes[i].Time, Suffix));
131 }
132 dumpHelper(Str, CumulativeMap, TotalTime);
133 Str << "Flat function times:\n";
134 DumpMapType FlatMap;
135 for (TimerIdT i = 0; i < LeafTimes.size(); ++i) {
136 FlatMap.insert(std::make_pair(LeafTimes[i], IDs[i]));
137 }
138 dumpHelper(Str, FlatMap, TotalTime);
139 Str << "Number of timer updates: " << StateChangeCount << "\n";
140 }
141
142 } // end of namespace Ice
OLDNEW
« src/IceOperand.cpp ('K') | « src/IceTimerTree.h ('k') | src/IceTranslator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698