gem5  v22.1.0.0
MN_TBEStorage.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-2022 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #ifndef __MEM_RUBY_STRUCTURES_MN_TBESTORAGE_HH__
39 #define __MEM_RUBY_STRUCTURES_MN_TBESTORAGE_HH__
40 
41 #include <cassert>
42 #include <unordered_map>
43 #include <vector>
44 
45 #include <base/statistics.hh>
46 
49 
50 namespace gem5
51 {
52 
53 namespace ruby
54 {
55 
56 // MN_TBEStorage is composed of multiple TBEStorage
57 // partitions that could be used for specific types of TBEs.
58 // Partition number 0 is the generic partition and will
59 // store any kind of TBEs.
60 // Space for specific TBEs will be looked first into the matching
61 // partition, and when no space is available the generic one will
62 // be used
63 template <class RetryEntry>
65 {
66  public:
68  std::initializer_list<TBEStorage *> _partitions)
69  : m_stats(parent),
70  partitions(_partitions)
71  {}
72 
73  // Returns the current number of slots allocated
74  int
75  size() const
76  {
77  int total = 0;
78  for (auto part : partitions) {
79  total += part->size();
80  }
81  return total;
82  }
83 
84  // Returns the total capacity of this TBEStorage table
85  int
86  capacity() const
87  {
88  int total = 0;
89  for (auto part : partitions) {
90  total += part->capacity();
91  }
92  return total;
93  }
94 
95  // Returns number of slots currently reserved
96  int
97  reserved() const
98  {
99  int total = 0;
100  for (auto part : partitions) {
101  total += part->reserved();
102  }
103  return total;
104  }
105 
106  // Returns the number of slots available for objects of a certain type;
107  int
108  slotsAvailable(int partition) const
109  {
110  auto generic_slots = partitions[0]->slotsAvailable();
111  if (partition) {
112  return partitions[partition]->slotsAvailable() +
113  generic_slots;
114  } else {
115  return generic_slots;
116  }
117  }
118 
119  // Returns the TBEStorage utilization
120  float utilization() const { return size() / (float)capacity(); }
121 
122  // Returns true if slotsAvailable(partition) >= n;
123  // current_time is always ignored
124  // This allows this class to be used with check_allocate in SLICC to
125  // trigger resource stalls when there are no slots available
126  bool
127  areNSlotsAvailable(int n, int partition,
128  Tick current_time = 0) const
129  {
130  return slotsAvailable(partition) >= n;
131  }
132 
133  // Increase/decrease the number of reserved slots. Having reserved slots
134  // reduces the number of slots available for allocation
135  void
136  incrementReserved(int partition)
137  {
138  if (partition &&
139  partitions[partition]->areNSlotsAvailable(1)) {
140  partitions[partition]->incrementReserved();
141  } else {
142  partitions[0]->incrementReserved();
143  }
145  }
146 
147  void
148  decrementReserved(int partition)
149  {
150  if (partition && (partitions[partition]->reserved() > 0)) {
151  partitions[partition]->decrementReserved();
152  } else {
153  partitions[0]->decrementReserved();
154  }
156  }
157 
158  // Assign a TBETable entry to a free slot and returns the slot number.
159  // Notice we don't need any info from TBETable and just track the number
160  // of entries assigned to each slot.
161  // This funcion requires slotsAvailable() > 0
162  int
163  addEntryToNewSlot(int partition)
164  {
165  if (partition && partitions[partition]->areNSlotsAvailable(1)) {
166  int part_slot = partitions[partition]->addEntryToNewSlot();
167 
168  m_stats.avg_size = size();
170 
171  return part_slot;
172  } else {
173  int generic_slot = partitions[0]->addEntryToNewSlot();
174 
175  m_stats.avg_size = size();
177 
178  return partitions[partition]->capacity() + generic_slot;
179  }
180  }
181 
182  // addEntryToSlot(int) is not supported.
183 
184  // Remove an entry from an existing non-empty slot. The slot becomes
185  // available again when the number of assigned entries == 0
186  void
187  removeEntryFromSlot(int slot, int partition)
188  {
189  auto part_capacity = partitions[partition]->capacity();
190  if (slot < part_capacity) {
191  partitions[partition]->removeEntryFromSlot(slot);
192  } else {
193  partitions[0]->removeEntryFromSlot(
194  slot - part_capacity);
195  }
196 
197  m_stats.avg_size = size();
199  }
200 
201  // Insert a "retry entry" into the queue
202  void
203  emplaceRetryEntry(RetryEntry entry)
204  {
205  m_retryEntries.push_back(entry);
206  }
207 
208  // Check if a retry is possible
209  bool
211  {
212  auto retry_iter = getNextRetryEntryIter();
213  return retry_iter != m_retryEntries.end();
214  }
215 
216  // Peek what the next thing to retry should be
217  // Should only be called if hasPossibleRetry() returns true
218  RetryEntry
220  {
221  auto retry_iter = getNextRetryEntryIter();
222  assert(retry_iter != m_retryEntries.end());
223 
224  auto entry = *retry_iter;
225 
226  m_retryEntries.erase(retry_iter);
227 
228  return entry;
229  }
230 
231  private:
233  {
235  : statistics::Group(parent),
236  ADD_STAT(avg_size, "Avg. number of slots allocated"),
237  ADD_STAT(avg_util, "Avg. utilization"),
238  ADD_STAT(avg_reserved, "Avg. number of slots reserved")
239  {}
240 
241  // Statistical variables
246 
248 
250 
253  {
254  auto begin_it = m_retryEntries.begin();
255  auto end_it = m_retryEntries.end();
256 
257  for (auto it = begin_it; it != end_it; it++) {
258  if (areNSlotsAvailable(1, it->getisNonSync()))
259  return it;
260  }
261 
262  return end_it;
263  }
264 };
265 
266 } // namespace ruby
267 
268 } // namespace gem5
269 
270 #endif
int addEntryToNewSlot(int partition)
std::list< RetryEntry >::iterator getNextRetryEntryIter()
void decrementReserved(int partition)
void removeEntryFromSlot(int slot, int partition)
bool areNSlotsAvailable(int n, int partition, Tick current_time=0) const
void emplaceRetryEntry(RetryEntry entry)
int slotsAvailable(int partition) const
void incrementReserved(int partition)
std::list< RetryEntry > m_retryEntries
std::vector< TBEStorage * > partitions
gem5::ruby::MN_TBEStorage::MN_TBEStorageStats m_stats
MN_TBEStorage(statistics::Group *parent, std::initializer_list< TBEStorage * > _partitions)
A stat that calculates the per tick average of a value.
Definition: statistics.hh:1959
Statistics container.
Definition: group.hh:94
STL vector class.
Definition: stl.hh:37
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
Bitfield< 31 > n
Definition: misc_types.hh:462
const FlagsType total
Print the total.
Definition: info.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Tick
Tick count type.
Definition: types.hh:58
Declaration of Statistics objects.
MN_TBEStorageStats(statistics::Group *parent)

Generated on Wed Dec 21 2022 10:22:38 for gem5 by doxygen 1.9.1