llvm.org GIT mirror llvm / f7d3b9b
[MCA] Store extra information about processor resources in the ResourceManager. Method ResourceManager::use() is responsible for updating the internal state of used processor resources, as well as notifying resource groups that contain used resources. Before this patch, method 'use()' didn't know how to quickly obtain the set of groups that contain a particular resource unit. It had to discover groups by perform a potentially slow search (done by iterating over the set of processor resource descriptors). With this patch, the relationship between resource units and groups is stored in the ResourceManager. That means, method 'use()' no longer has to search for groups. This gives an average speedup of ~4-5% on a release build. This patch also adds extra code comments in ResourceManager.h to better describe the resource mask layout, and how resouce indices are computed from resource masks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350387 91177308-0d34-0410-b5e6-96231b3b80d8 Andrea Di Biagio 1 year, 10 months ago
2 changed file(s) with 86 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
138138 /// An index to the MCProcResourceDesc entry in the processor model.
139139 const unsigned ProcResourceDescIndex;
140140 /// A resource mask. This is generated by the tool with the help of
141 /// function `mca::createProcResourceMasks' (see Support.h).
141 /// function `mca::computeProcResourceMasks' (see Support.h).
142 ///
143 /// Field ResourceMask only has one bit set if this resource state describes a
144 /// processor resource unit (i.e. this is not a group). That means, we can
145 /// quickly check if a resource is a group by simply counting the number of
146 /// bits that are set in the mask.
147 ///
148 /// The most significant bit of a mask (MSB) uniquely identifies a resource.
149 /// Remaining bits are used to describe the composition of a group (Group).
150 ///
151 /// Example (little endian):
152 /// Resource | Mask | MSB | Group
153 /// ---------+------------+------------+------------
154 /// A | 0b000001 | 0b000001 | 0b000000
155 /// | | |
156 /// B | 0b000010 | 0b000010 | 0b000000
157 /// | | |
158 /// C | 0b010000 | 0b010000 | 0b000000
159 /// | | |
160 /// D | 0b110010 | 0b100000 | 0b010010
161 ///
162 /// In this example, resources A, B and C are processor resource units.
163 /// Only resource D is a group resource, and it contains resources B and C.
164 /// That is because MSB(B) and MSB(C) are both contained within Group(D).
142165 const uint64_t ResourceMask;
143166
144167 /// A ProcResource can have multiple units.
278301 /// In future, it can be extended to support itineraries too through the same
279302 /// public interface.
280303 class ResourceManager {
281 // The resource manager owns all the ResourceState.
304 // Set of resources available on the subtarget.
305 //
306 // There is an instance of ResourceState for every resource declared by the
307 // target scheduling model.
308 //
309 // Elements of this vector are ordered by resource kind. In particular,
310 // resource units take precedence over resource groups.
311 //
312 // The index of a processor resource in this vector depends on the value of
313 // its mask (see the description of field ResourceState::ResourceMask). In
314 // particular, it is computed as the position of the most significant bit set
315 // (MSB) in the mask plus one (since we want to ignore the invalid resource
316 // descriptor at index zero).
317 //
318 // Example (little endian):
319 //
320 // Resource | Mask | MSB | Index
321 // ---------+---------+---------+-------
322 // A | 0b00001 | 0b00001 | 1
323 // | | |
324 // B | 0b00100 | 0b00100 | 3
325 // | | |
326 // C | 0b10010 | 0b10000 | 5
327 //
328 //
329 // The same index is also used to address elements within vector `Strategies`
330 // and vector `Resource2Groups`.
282331 std::vector> Resources;
283332 std::vector> Strategies;
333
334 // Used to quickly identify groups that own a particular resource unit.
335 std::vector Resource2Groups;
284336
285337 // Keeps track of which resources are busy, and how many cycles are left
286338 // before those become usable again.
114114 return std::unique_ptr(nullptr);
115115 }
116116
117 ResourceManager::ResourceManager(const MCSchedModel &SM) {
117 ResourceManager::ResourceManager(const MCSchedModel &SM)
118 : Resources(SM.getNumProcResourceKinds()),
119 Strategies(SM.getNumProcResourceKinds()),
120 Resource2Groups(SM.getNumProcResourceKinds(), 0) {
118121 computeProcResourceMasks(SM, ProcResID2Mask);
119 Resources.resize(SM.getNumProcResourceKinds());
120 Strategies.resize(SM.getNumProcResourceKinds());
121122
122123 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
123124 uint64_t Mask = ProcResID2Mask[I];
125126 Resources[Index] =
126127 llvm::make_unique(*SM.getProcResource(I), I, Mask);
127128 Strategies[Index] = getStrategyFor(*Resources[Index]);
129 }
130
131 for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
132 uint64_t Mask = ProcResID2Mask[I];
133 unsigned Index = getResourceStateIndex(Mask);
134 const ResourceState &RS = *Resources[Index];
135 if (!RS.isAResourceGroup())
136 continue;
137
138 uint64_t GroupMaskIdx = 1ULL << (Index - 1);
139 Mask -= GroupMaskIdx;
140 while (Mask) {
141 // Extract lowest set isolated bit.
142 uint64_t Unit = Mask & (-Mask);
143 unsigned IndexUnit = getResourceStateIndex(Unit);
144 Resource2Groups[IndexUnit] |= GroupMaskIdx;
145 Mask ^= Unit;
146 }
128147 }
129148 }
130149
178197 if (RS.isReady())
179198 return;
180199
181 // Notify to other resources that RR.first is no longer available.
182 for (std::unique_ptr &Res : Resources) {
183 ResourceState &Current = *Res;
184 if (!Current.isAResourceGroup() || Current.getResourceMask() == RR.first)
185 continue;
186
187 if (Current.containsResource(RR.first)) {
188 unsigned Index = getResourceStateIndex(Current.getResourceMask());
189 Current.markSubResourceAsUsed(RR.first);
190 Strategies[Index]->used(RR.first);
191 }
200 // Notify groups that RR.first is no longer available.
201 uint64_t Users = Resource2Groups[RSID];
202 while (Users) {
203 // Extract lowest set isolated bit.
204 unsigned GroupIndex = getResourceStateIndex(Users & (-Users));
205 ResourceState &CurrentUser = *Resources[GroupIndex];
206 CurrentUser.markSubResourceAsUsed(RR.first);
207 Strategies[GroupIndex]->used(RR.first);
208 // Reset lowest set bit.
209 Users &= Users - 1;
192210 }
193211 }
194212