gem5  v20.0.0.2
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
VIPERCoalescer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2015 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 #include "base/logging.hh"
35 #include "base/str.hh"
36 #include "config/the_isa.hh"
37 
38 #if THE_ISA == X86_ISA
40 
41 #endif // X86_ISA
43 
45 #include "debug/GPUCoalescer.hh"
46 #include "debug/MemoryAccess.hh"
47 #include "mem/packet.hh"
56 #include "params/VIPERCoalescer.hh"
57 
58 using namespace std;
59 
61 VIPERCoalescerParams::create()
62 {
63  return new VIPERCoalescer(this);
64 }
65 
67  : GPUCoalescer(p)
68 {
69  m_max_wb_per_cycle=p->max_wb_per_cycle;
70  m_max_inv_per_cycle=p->max_inv_per_cycle;
72  m_outstanding_wb = 0;
73 }
74 
76 {
77 }
78 
79 // Places an uncoalesced packet in uncoalescedTable. If the packet is a
80 // special type (MemFence, scoping, etc), it is issued immediately.
81 RequestStatus
83 {
86  "There are %d Writebacks and %d Invalidatons\n",
88  }
89  // Are we in the middle of a release
90  if ((m_outstanding_wb) > 0) {
91  if (pkt->req->isKernel()) {
92  // Everythign is fine
93  // Barriers and Kernel End scan coalesce
94  // If it is a Kerenl Begin flush the cache
95  if (pkt->req->isAcquire() && (m_outstanding_inv == 0)) {
96  invL1();
97  }
98 
99  if (pkt->req->isRelease()) {
100  insertKernel(pkt->req->contextId(), pkt);
101  }
102 
103  return RequestStatus_Issued;
104  }
105  } else if (pkt->req->isKernel() && pkt->req->isRelease()) {
106  // Flush Dirty Data on Kernel End
107  // isKernel + isRelease
108  insertKernel(pkt->req->contextId(), pkt);
109  wbL1();
110  if (m_outstanding_wb == 0) {
111  for (auto it = kernelEndList.begin(); it != kernelEndList.end(); it++) {
112  newKernelEnds.push_back(it->first);
113  }
114  completeIssue();
115  }
116  return RequestStatus_Issued;
117  }
118 
120 
121  if (pkt->req->isKernel() && pkt->req->isAcquire()) {
122  // Invalidate clean Data on Kernel Begin
123  // isKernel + isAcquire
124  invL1();
125  } else if (pkt->req->isAcquire() && pkt->req->isRelease()) {
126  // Deschedule the AtomicAcqRel and
127  // Flush and Invalidate the L1 cache
128  invwbL1();
129  if (m_outstanding_wb > 0 && issueEvent.scheduled()) {
130  DPRINTF(GPUCoalescer, "issueEvent Descheduled\n");
132  }
133  } else if (pkt->req->isRelease()) {
134  // Deschedule the StoreRel and
135  // Flush the L1 cache
136  wbL1();
137  if (m_outstanding_wb > 0 && issueEvent.scheduled()) {
138  DPRINTF(GPUCoalescer, "issueEvent Descheduled\n");
140  }
141  } else if (pkt->req->isAcquire()) {
142  // LoadAcq or AtomicAcq
143  // Invalidate the L1 cache
144  invL1();
145  }
146  // Request was successful
147  if (m_outstanding_wb == 0) {
148  if (!issueEvent.scheduled()) {
149  DPRINTF(GPUCoalescer, "issueEvent Rescheduled\n");
151  }
152  }
153  return RequestStatus_Issued;
154 }
155 
156 void
158 {
160  // if L1 Flush Complete
161  // attemnpt to schedule issueEvent
162  assert(((int) m_outstanding_wb) >= 0);
163  if (m_outstanding_wb == 0) {
164  for (auto it = kernelEndList.begin(); it != kernelEndList.end(); it++) {
165  newKernelEnds.push_back(it->first);
166  }
167  completeIssue();
168  }
169  trySendRetries();
170 }
171 
172 void
174 {
176  // if L1 Flush Complete
177  // attemnpt to schedule issueEvent
178  // This probably won't happen, since
179  // we dont wait on cache invalidations
180  if (m_outstanding_wb == 0) {
181  for (auto it = kernelEndList.begin(); it != kernelEndList.end(); it++) {
182  newKernelEnds.push_back(it->first);
183  }
184  completeIssue();
185  }
186  trySendRetries();
187 }
188 
192 void
194 {
195  int size = m_dataCache_ptr->getNumBlocks();
197  "There are %d Invalidations outstanding before Cache Walk\n",
199  // Walk the cache
200  for (int i = 0; i < size; i++) {
202  // Evict Read-only data
203  RubyRequestType request_type = RubyRequestType_REPLACEMENT;
204  std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
205  clockEdge(), addr, (uint8_t*) 0, 0, 0,
206  request_type, RubyAccessMode_Supervisor,
207  nullptr);
208  assert(m_mandatory_q_ptr != NULL);
209  Tick latency = cyclesToTicks(
210  m_controller->mandatoryQueueLatency(request_type));
211  assert(latency > 0);
212  m_mandatory_q_ptr->enqueue(msg, clockEdge(), latency);
214  }
216  "There are %d Invalidatons outstanding after Cache Walk\n",
218 }
219 
223 void
225 {
226  int size = m_dataCache_ptr->getNumBlocks();
228  "There are %d Writebacks outstanding before Cache Walk\n",
230  // Walk the cache
231  for (int i = 0; i < size; i++) {
233  // Write dirty data back
234  RubyRequestType request_type = RubyRequestType_FLUSH;
235  std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
236  clockEdge(), addr, (uint8_t*) 0, 0, 0,
237  request_type, RubyAccessMode_Supervisor,
238  nullptr);
239  assert(m_mandatory_q_ptr != NULL);
240  Tick latency = cyclesToTicks(
241  m_controller->mandatoryQueueLatency(request_type));
242  assert(latency > 0);
243  m_mandatory_q_ptr->enqueue(msg, clockEdge(), latency);
245  }
247  "There are %d Writebacks outstanding after Cache Walk\n",
249 }
250 
254 void
256 {
257  int size = m_dataCache_ptr->getNumBlocks();
258  // Walk the cache
259  for (int i = 0; i < size; i++) {
261  // Evict Read-only data
262  RubyRequestType request_type = RubyRequestType_REPLACEMENT;
263  std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
264  clockEdge(), addr, (uint8_t*) 0, 0, 0,
265  request_type, RubyAccessMode_Supervisor,
266  nullptr);
267  assert(m_mandatory_q_ptr != NULL);
268  Tick latency = cyclesToTicks(
269  m_controller->mandatoryQueueLatency(request_type));
270  assert(latency > 0);
271  m_mandatory_q_ptr->enqueue(msg, clockEdge(), latency);
273  }
274  // Walk the cache
275  for (int i = 0; i< size; i++) {
277  // Write dirty data back
278  RubyRequestType request_type = RubyRequestType_FLUSH;
279  std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
280  clockEdge(), addr, (uint8_t*) 0, 0, 0,
281  request_type, RubyAccessMode_Supervisor,
282  nullptr);
283  assert(m_mandatory_q_ptr != NULL);
284  Tick latency = cyclesToTicks(
285  m_controller->mandatoryQueueLatency(request_type));
286  assert(latency > 0);
287  m_mandatory_q_ptr->enqueue(msg, clockEdge(), latency);
289  }
290 }
#define DPRINTF(x,...)
Definition: trace.hh:222
void insertKernel(int wavefront_id, PacketPtr pkt)
EventFunctionWrapper issueEvent
Bitfield< 7 > i
AbstractController * m_controller
Definition: RubyPort.hh:189
ip6_addr_t addr
Definition: inet.hh:330
void trySendRetries()
Definition: RubyPort.cc:449
void wbCallback(Addr address)
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
uint64_t m_outstanding_wb
void completeIssue()
uint64_t m_outstanding_inv
RequestPtr req
A pointer to the original request.
Definition: packet.hh:321
RubyGPUCoalescerParams Params
void wbL1()
Writeback L1 cache (Release)
uint64_t m_max_wb_per_cycle
Tick cyclesToTicks(Cycles c) const
Tick curTick()
The current simulated tick.
Definition: core.hh:44
void invCallback(Addr address)
CacheMemory * m_dataCache_ptr
uint64_t Tick
Tick count type.
Definition: types.hh:61
virtual RequestStatus makeRequest(PacketPtr pkt) override
void invL1()
Invalidate L1 cache (Acquire)
RequestStatus makeRequest(PacketPtr pkt)
void deschedule(Event &event)
Definition: eventq.hh:1007
void schedule(Event &event, Tick when)
Definition: eventq.hh:998
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:249
std::unordered_map< int, PacketPtr > kernelEndList
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Addr getAddressAtIdx(int idx) const
Definition: CacheMemory.cc:153
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
MessageBuffer * m_mandatory_q_ptr
Definition: RubyPort.hh:190
std::vector< int > newKernelEnds
Declaration of the Packet class.
virtual Cycles mandatoryQueueLatency(const RubyRequestType &param_type)
void invwbL1()
Invalidate and Writeback L1 cache (Acquire&Release)
uint64_t m_max_inv_per_cycle
Bitfield< 0 > p
int getNumBlocks() const
Definition: CacheMemory.hh:155
void enqueue(MsgPtr message, Tick curTime, Tick delta)
VIPERCoalescer(const Params *)

Generated on Mon Jun 8 2020 15:45:12 for gem5 by doxygen 1.8.13