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

Side by Side Diff: src/IceTimerTree.cpp

Issue 878383004: Subzero: Fix timers for multithreaded translation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Cleanup Created 5 years, 10 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
1 //===- subzero/src/IceTimerTree.cpp - Pass timer defs ---------------------===// 1 //===- subzero/src/IceTimerTree.cpp - Pass timer defs ---------------------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file defines the TimerTree class, which tracks flat and 10 // This file defines the TimerTree class, which tracks flat and
11 // cumulative execution time collection of call chains. 11 // cumulative execution time collection of call chains.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "llvm/Support/Timer.h" 15 #include "llvm/Support/Timer.h"
16 16
17 #include "IceDefs.h" 17 #include "IceDefs.h"
18 #include "IceTimerTree.h" 18 #include "IceTimerTree.h"
19 19
20 namespace Ice { 20 namespace Ice {
21 21
22 TimerStack::TimerStack(const IceString &Name) 22 TimerStack::TimerStack(const IceString &Name)
23 : Name(Name), FirstTimestamp(timestamp()), LastTimestamp(FirstTimestamp), 23 : Name(Name), FirstTimestamp(timestamp()), LastTimestamp(FirstTimestamp),
24 StateChangeCount(0), StackTop(0) { 24 StateChangeCount(0), StackTop(0) {
25 if (!ALLOW_DUMP) 25 if (!ALLOW_DUMP)
26 return; 26 return;
27 Nodes.resize(1); // Reserve Nodes[0] for the root node. 27 Nodes.resize(1); // Reserve Nodes[0] for the root node (sentinel).
28 IDs.resize(TT__num); 28 IDs.resize(TT__num);
29 LeafTimes.resize(TT__num);
30 LeafCounts.resize(TT__num);
29 #define STR(s) #s 31 #define STR(s) #s
30 #define X(tag) \ 32 #define X(tag) \
31 IDs[TT_##tag] = STR(tag); \ 33 IDs[TT_##tag] = STR(tag); \
32 IDsIndex[STR(tag)] = TT_##tag; 34 IDsIndex[STR(tag)] = TT_##tag;
33 TIMERTREE_TABLE; 35 TIMERTREE_TABLE;
34 #undef X 36 #undef X
35 #undef STR 37 #undef STR
36 } 38 }
37 39
38 // Returns the unique timer ID for the given Name, creating a new ID 40 // Returns the unique timer ID for the given Name, creating a new ID
39 // if needed. 41 // if needed.
40 TimerIdT TimerStack::getTimerID(const IceString &Name) { 42 TimerIdT TimerStack::getTimerID(const IceString &Name) {
41 if (!ALLOW_DUMP) 43 if (!ALLOW_DUMP)
42 return 0; 44 return 0;
43 if (IDsIndex.find(Name) == IDsIndex.end()) { 45 if (IDsIndex.find(Name) == IDsIndex.end()) {
44 IDsIndex[Name] = IDs.size(); 46 IDsIndex[Name] = IDs.size();
45 IDs.push_back(Name); 47 IDs.push_back(Name);
48 LeafTimes.push_back(decltype(LeafTimes)::value_type());
49 LeafCounts.push_back(decltype(LeafCounts)::value_type());
46 } 50 }
47 return IDsIndex[Name]; 51 return IDsIndex[Name];
48 } 52 }
49 53
54 // Creates a mapping from TimerIdT (leaf) values in the Src timer
55 // stack into TimerIdT values in this timer stack. Creates new
56 // entries in this timer stack as needed.
57 TimerStack::TranslationType
58 TimerStack::translateIDsFrom(const TimerStack &Src) {
59 size_t Size = Src.IDs.size();
60 TranslationType Mapping(Size);
61 for (TimerIdT i = 0; i < Size; ++i) {
62 Mapping[i] = getTimerID(Src.IDs[i]);
63 }
64 return Mapping;
65 }
66
67 // Merges two timer stacks, by combining and summing corresponding
68 // entries. This timer stack is updated from Src.
69 void TimerStack::mergeFrom(const TimerStack &Src) {
70 if (!ALLOW_DUMP)
71 return;
72 TranslationType Mapping = translateIDsFrom(Src);
73 TTindex Index = 0;
jvoung (off chromium) 2015/01/30 18:42:56 So the TimerIDs might need mapping, but the TTinde
Jim Stichnoth 2015/01/30 20:22:25 No, they need mapping too. The "Index" variable i
74 for (const TimerTreeNode &Node : Src.Nodes) {
75 // The first node is reserved as a sentinel, so avoid it.
76 if (Index > 0) {
77 // Find the full path to the Src node, translated to path
78 // components corresponding to this timer stack.
79 PathType Path = Src.getPath(Index, Mapping);
80 // Find a node in this timer stack corresponding to the given
81 // path, creating new interior nodes as necessary.
82 TTindex MyIndex = findPath(Path);
83 Nodes[MyIndex].Time += Node.Time;
84 Nodes[MyIndex].UpdateCount += Node.UpdateCount;
85 }
86 ++Index;
87 }
88 for (TimerIdT i = 0; i < Src.LeafTimes.size(); ++i) {
89 LeafTimes[Mapping[i]] += Src.LeafTimes[i];
90 LeafCounts[Mapping[i]] += Src.LeafCounts[i];
91 }
92 StateChangeCount += Src.StateChangeCount;
93 }
94
95 // Constructs a path consisting of the sequence of leaf values leading
96 // to a given node, with the Mapping translation applied to the leaf
97 // values. The path ends up being in "reverse" order, i.e. from leaf
98 // to root.
99 TimerStack::PathType TimerStack::getPath(TTindex Index,
100 const TranslationType &Mapping) const {
101 PathType Path;
102 while (Index) {
103 Path.push_back(Mapping[Nodes[Index].Interior]);
104 assert(Nodes[Index].Parent < Index);
105 Index = Nodes[Index].Parent;
106 }
107 return Path;
108 }
109
110 // Given a parent node and a leaf ID, returns the index of the
111 // parent's child ID, creating a new node for the child as necessary.
112 TimerStack::TTindex TimerStack::getChildIndex(TimerStack::TTindex Parent,
113 TimerIdT ID) {
114 if (Nodes[Parent].Children.size() <= ID)
115 Nodes[Parent].Children.resize(ID + 1);
116 if (Nodes[Parent].Children[ID] == 0) {
117 TTindex Size = Nodes.size();
118 Nodes[Parent].Children[ID] = Size;
119 Nodes.resize(Size + 1);
120 Nodes[Size].Parent = Parent;
121 Nodes[Size].Interior = ID;
122 }
123 return Nodes[Parent].Children[ID];
124 }
125
126 // Finds a node in the timer stack corresponding to the given path,
127 // creating new interior nodes as necessary.
128 TimerStack::TTindex TimerStack::findPath(const PathType &Path) {
129 TTindex CurIndex = 0;
130 // The path is in reverse order (leaf to root), so it needs to be
131 // followed in reverse.
132 for (TTindex Index : reverse_range(Path)) {
133 CurIndex = getChildIndex(CurIndex, Index);
134 }
135 assert(CurIndex); // shouldn't be the sentinel node
136 return CurIndex;
137 }
138
50 // Pushes a new marker onto the timer stack. 139 // Pushes a new marker onto the timer stack.
51 void TimerStack::push(TimerIdT ID) { 140 void TimerStack::push(TimerIdT ID) {
52 if (!ALLOW_DUMP) 141 if (!ALLOW_DUMP)
53 return; 142 return;
54 const bool UpdateCounts = false; 143 const bool UpdateCounts = false;
55 update(UpdateCounts); 144 update(UpdateCounts);
56 if (Nodes[StackTop].Children.size() <= ID) 145 StackTop = getChildIndex(StackTop, ID);
57 Nodes[StackTop].Children.resize(ID + 1); 146 assert(StackTop);
58 if (Nodes[StackTop].Children[ID] == 0) {
59 TTindex Size = Nodes.size();
60 Nodes[StackTop].Children[ID] = Size;
61 Nodes.resize(Size + 1);
62 Nodes[Size].Parent = StackTop;
63 Nodes[Size].Interior = ID;
64 }
65 StackTop = Nodes[StackTop].Children[ID];
66 } 147 }
67 148
68 // Pop the top marker from the timer stack. Validates via assert() 149 // Pops the top marker from the timer stack. Validates via assert()
69 // that the expected marker is popped. 150 // that the expected marker is popped.
70 void TimerStack::pop(TimerIdT ID) { 151 void TimerStack::pop(TimerIdT ID) {
71 if (!ALLOW_DUMP) 152 if (!ALLOW_DUMP)
72 return; 153 return;
73 const bool UpdateCounts = true; 154 const bool UpdateCounts = true;
74 update(UpdateCounts); 155 update(UpdateCounts);
75 assert(StackTop); 156 assert(StackTop);
76 assert(Nodes[StackTop].Parent < StackTop); 157 assert(Nodes[StackTop].Parent < StackTop);
77 // Verify that the expected ID is being popped. 158 // Verify that the expected ID is being popped.
78 assert(Nodes[StackTop].Interior == ID); 159 assert(Nodes[StackTop].Interior == ID);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 dumpHelper(Str, FlatMap, TotalTime); 299 dumpHelper(Str, FlatMap, TotalTime);
219 Str << "Number of timer updates: " << StateChangeCount << "\n"; 300 Str << "Number of timer updates: " << StateChangeCount << "\n";
220 } 301 }
221 302
222 double TimerStack::timestamp() { 303 double TimerStack::timestamp() {
223 // TODO: Implement in terms of std::chrono for C++11. 304 // TODO: Implement in terms of std::chrono for C++11.
224 return llvm::TimeRecord::getCurrentTime(false).getWallTime(); 305 return llvm::TimeRecord::getCurrentTime(false).getWallTime();
225 } 306 }
226 307
227 } // end of namespace Ice 308 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698