gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 // return the min number of elements that the manager can reserve given
41 // a request for "size" elements
42 uint32_t
44 {
45  fatal_if(size <= 0 || size > poolSize(), "Illegal VGPR region size=%d\n",
46  size);
47 
48  return size % minAllocation() > 0 ?
49  (minAllocation() - (size % minAllocation())) + size : size;
50 }
51 
52 std::string
54 {
55  std::string _cout;
56  uint32_t reservedEntries = 0;
57 
58  /*
59  Iterate over all elements in freeSpaceRecord, checking first element
60  of each pair to see how much space in it has been allocated already.
61  This only counts the partially allocated regions. Thus, in addition,
62  count the elements in reservedSpaceRecord.
63  */
64  auto it_free = freeSpaceRecord.begin();
65  while (it_free != freeSpaceRecord.end()) {
66  reservedEntries += it_free->first;
67  ++it_free;
68  }
69  reservedEntries += (reservedSpaceRecord * totalRegSpace);
70 
71  if (reservedEntries == 0)
72  _cout = "VRF is empty\n";
73  else {
74  _cout = "VRF reserves " + std::to_string(reservedEntries) + " VGPRs\n";
75  }
76  return _cout;
77 }
78 
79 // reset freeSpace and reservedSpace
80 void
81 DynPoolManager::resetRegion(const int & regsPerSimd){
82  totalRegSpace = regsPerSimd;
84  freeSpaceRecord.clear();
85 
86  // reset available free space
87  _totRegSpaceAvailable = regsPerSimd;
88  freeSpaceRecord.push_back(std::make_pair(0,regsPerSimd));
89 }
90 
91 bool
92 DynPoolManager::canAllocate(uint32_t numRegions, uint32_t size)
93 {
94  uint32_t actualSize = minAllocatedElements(size);
95  DPRINTF(GPUVRF,"Can Allocate %d\n",actualSize);
96  return (_totRegSpaceAvailable >= actualSize);
97 }
98 
99 uint32_t
100 DynPoolManager::allocateRegion(const uint32_t size,
101  uint32_t *reservedPoolSize)
102 {
103  uint32_t startIdx = (unsigned)-1;
104  uint32_t actualSize = minAllocatedElements(size);
105  auto it = freeSpaceRecord.begin();
106  while (it != freeSpaceRecord.end()) {
107  if (it->second >= actualSize) {
108  // assign the next block starting from here
109  startIdx = it->first;
110  _regionSize = actualSize;
111  *reservedPoolSize = actualSize;
112  _totRegSpaceAvailable -= actualSize;
113 
114  // This case sees if this chunk size is exactly equal to
115  // the size of the requested chunk. If yes, then this can't
116  // contribute to future requests and hence, should be removed
117  if (it->second == actualSize) {
118  it = freeSpaceRecord.erase(it);
119  // once entire freeSpaceRecord allocated, increment
120  // reservedSpaceRecord count
122  } else {
123  it->first += actualSize;
124  it->second -= actualSize;
125  }
126  break;
127  }
128  it++;
129  }
130  DPRINTF(GPUVRF,"totRegSpace %d allocating Register at %d and"
131  " size %d\n",_totRegSpaceAvailable,startIdx,actualSize);
132  return startIdx;
133 }
134 
135 void
136 DynPoolManager::freeRegion(uint32_t firstIdx,
137  uint32_t lastIdx)
138 {
139  // lastIdx-firstIdx should give the size of free space
140  DPRINTF(GPUVRF,"freeing Region at %d %d, size %d\n",
141  firstIdx,lastIdx,lastIdx-firstIdx);
142 
143  // Current dynamic register allocation does not handle wraparound
144  assert(firstIdx < lastIdx);
145  _totRegSpaceAvailable += lastIdx-firstIdx;
146  freeSpaceRecord.push_back(std::make_pair(firstIdx,lastIdx-firstIdx));
147  // remove corresponding entry from reservedSpaceRecord too
149 }
150 
151 uint32_t
153 {
154  bool wrapAround = (region.first > region.second);
155  if (!wrapAround) {
156  return region.second - region.first + 1;
157  } else {
158  return region.second + poolSize() - region.first + 1;
159  }
160 }
DynPoolManager::canAllocate
bool canAllocate(uint32_t numRegions, uint32_t size) override
Definition: dyn_pool_manager.cc:92
DynPoolManager::allocateRegion
uint32_t allocateRegion(const uint32_t size, uint32_t *reservedPoolSize) override
Definition: dyn_pool_manager.cc:100
sc_dt::to_string
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:91
DynPoolManager::_regionSize
uint32_t _regionSize
Definition: dyn_pool_manager.hh:65
dyn_pool_manager.hh
DynPoolManager::resetRegion
void resetRegion(const int &regsPerSimd) override
Definition: dyn_pool_manager.cc:81
DynPoolManager::printRegion
std::string printRegion() override
Definition: dyn_pool_manager.cc:53
DynPoolManager::_totRegSpaceAvailable
uint32_t _totRegSpaceAvailable
Definition: dyn_pool_manager.hh:67
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
DynPoolManager::minAllocatedElements
uint32_t minAllocatedElements(uint32_t size)
Definition: dyn_pool_manager.cc:43
PoolManager::minAllocation
uint32_t minAllocation()
Definition: pool_manager.hh:50
DynPoolManager::reservedSpaceRecord
int reservedSpaceRecord
Definition: dyn_pool_manager.hh:70
std::pair
STL pair class.
Definition: stl.hh:58
DynPoolManager::regionSize
uint32_t regionSize(std::pair< uint32_t, uint32_t > &region) override
Definition: dyn_pool_manager.cc:152
DynPoolManager::freeRegion
void freeRegion(uint32_t firstIdx, uint32_t lastIdx) override
Definition: dyn_pool_manager.cc:136
logging.hh
DynPoolManager::totalRegSpace
int totalRegSpace
Definition: dyn_pool_manager.hh:72
PoolManager::poolSize
uint32_t poolSize()
Definition: pool_manager.hh:59
trace.hh
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:219
DynPoolManager::freeSpaceRecord
std::list< std::pair< int, int > > freeSpaceRecord
Definition: dyn_pool_manager.hh:69

Generated on Tue Jun 22 2021 15:28:28 for gem5 by doxygen 1.8.17