gem5  v21.1.0.2
dyn_pool_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 #include "base/logging.hh"
36 #include "base/trace.hh"
37 #include "debug/GPUVRF.hh"
39 
40 namespace gem5
41 {
42 
43 // return the min number of elements that the manager can reserve given
44 // a request for "size" elements
45 uint32_t
47 {
48  fatal_if(size <= 0 || size > poolSize(), "Illegal VGPR region size=%d\n",
49  size);
50 
51  return size % minAllocation() > 0 ?
52  (minAllocation() - (size % minAllocation())) + size : size;
53 }
54 
55 std::string
57 {
58  std::string _cout;
59  uint32_t reservedEntries = 0;
60 
61  /*
62  Iterate over all elements in freeSpaceRecord, checking first element
63  of each pair to see how much space in it has been allocated already.
64  This only counts the partially allocated regions. Thus, in addition,
65  count the elements in reservedSpaceRecord.
66  */
67  auto it_free = freeSpaceRecord.begin();
68  while (it_free != freeSpaceRecord.end()) {
69  reservedEntries += it_free->first;
70  ++it_free;
71  }
72  reservedEntries += (reservedSpaceRecord * totalRegSpace);
73 
74  if (reservedEntries == 0)
75  _cout = "VRF is empty\n";
76  else {
77  _cout = "VRF reserves " + std::to_string(reservedEntries) + " VGPRs\n";
78  }
79  return _cout;
80 }
81 
82 // reset freeSpace and reservedSpace
83 void
84 DynPoolManager::resetRegion(const int & regsPerSimd){
85  totalRegSpace = regsPerSimd;
87  freeSpaceRecord.clear();
88 
89  // reset available free space
90  _totRegSpaceAvailable = regsPerSimd;
91  freeSpaceRecord.push_back(std::make_pair(0,regsPerSimd));
92 }
93 
94 bool
95 DynPoolManager::canAllocate(uint32_t numRegions, uint32_t size)
96 {
97  uint32_t actualSize = minAllocatedElements(size);
98  DPRINTF(GPUVRF,"Can Allocate %d\n",actualSize);
99  return (_totRegSpaceAvailable >= actualSize);
100 }
101 
102 uint32_t
103 DynPoolManager::allocateRegion(const uint32_t size,
104  uint32_t *reservedPoolSize)
105 {
106  uint32_t startIdx = (unsigned)-1;
107  uint32_t actualSize = minAllocatedElements(size);
108  auto it = freeSpaceRecord.begin();
109  while (it != freeSpaceRecord.end()) {
110  if (it->second >= actualSize) {
111  // assign the next block starting from here
112  startIdx = it->first;
113  _regionSize = actualSize;
114  *reservedPoolSize = actualSize;
115  _totRegSpaceAvailable -= actualSize;
116 
117  // This case sees if this chunk size is exactly equal to
118  // the size of the requested chunk. If yes, then this can't
119  // contribute to future requests and hence, should be removed
120  if (it->second == actualSize) {
121  it = freeSpaceRecord.erase(it);
122  // once entire freeSpaceRecord allocated, increment
123  // reservedSpaceRecord count
125  } else {
126  it->first += actualSize;
127  it->second -= actualSize;
128  }
129  break;
130  }
131  it++;
132  }
133  DPRINTF(GPUVRF,"totRegSpace %d allocating Register at %d and"
134  " size %d\n",_totRegSpaceAvailable,startIdx,actualSize);
135  return startIdx;
136 }
137 
138 void
139 DynPoolManager::freeRegion(uint32_t firstIdx,
140  uint32_t lastIdx)
141 {
142  // lastIdx-firstIdx should give the size of free space
143  DPRINTF(GPUVRF,"freeing Region at %d %d, size %d\n",
144  firstIdx,lastIdx,lastIdx-firstIdx);
145 
146  // Current dynamic register allocation does not handle wraparound
147  assert(firstIdx < lastIdx);
148  _totRegSpaceAvailable += lastIdx-firstIdx;
149  freeSpaceRecord.push_back(std::make_pair(firstIdx,lastIdx-firstIdx));
150  // remove corresponding entry from reservedSpaceRecord too
152 }
153 
154 uint32_t
156 {
157  bool wrapAround = (region.first > region.second);
158  if (!wrapAround) {
159  return region.second - region.first + 1;
160  } else {
161  return region.second + poolSize() - region.first + 1;
162  }
163 }
164 
165 } // namespace gem5
gem5::DynPoolManager::regionSize
uint32_t regionSize(std::pair< uint32_t, uint32_t > &region) override
Definition: dyn_pool_manager.cc:155
gem5::DynPoolManager::freeSpaceRecord
std::list< std::pair< int, int > > freeSpaceRecord
Definition: dyn_pool_manager.hh:72
gem5::DynPoolManager::totalRegSpace
int totalRegSpace
Definition: dyn_pool_manager.hh:75
sc_dt::to_string
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:91
gem5::DynPoolManager::canAllocate
bool canAllocate(uint32_t numRegions, uint32_t size) override
Definition: dyn_pool_manager.cc:95
dyn_pool_manager.hh
gem5::DynPoolManager::minAllocatedElements
uint32_t minAllocatedElements(uint32_t size)
Definition: dyn_pool_manager.cc:46
gem5::DynPoolManager::resetRegion
void resetRegion(const int &regsPerSimd) override
Definition: dyn_pool_manager.cc:84
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::PoolManager::minAllocation
uint32_t minAllocation()
Definition: pool_manager.hh:53
gem5::DynPoolManager::_regionSize
uint32_t _regionSize
Definition: dyn_pool_manager.hh:68
gem5::DynPoolManager::allocateRegion
uint32_t allocateRegion(const uint32_t size, uint32_t *reservedPoolSize) override
Definition: dyn_pool_manager.cc:103
gem5::DynPoolManager::_totRegSpaceAvailable
uint32_t _totRegSpaceAvailable
Definition: dyn_pool_manager.hh:70
std::pair
STL pair class.
Definition: stl.hh:58
gem5::DynPoolManager::printRegion
std::string printRegion() override
Definition: dyn_pool_manager.cc:56
logging.hh
gem5::DynPoolManager::reservedSpaceRecord
int reservedSpaceRecord
Definition: dyn_pool_manager.hh:73
trace.hh
gem5::DynPoolManager::freeRegion
void freeRegion(uint32_t firstIdx, uint32_t lastIdx) override
Definition: dyn_pool_manager.cc:139
gem5::PoolManager::poolSize
uint32_t poolSize()
Definition: pool_manager.hh:62
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:225
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40

Generated on Tue Sep 21 2021 12:25:23 for gem5 by doxygen 1.8.17