gem5  v21.1.0.2
GPUCoalescer.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 
35 
36 #include "base/compiler.hh"
37 #include "base/logging.hh"
38 #include "base/str.hh"
40 #include "debug/GPUCoalescer.hh"
41 #include "debug/MemoryAccess.hh"
42 #include "debug/ProtocolTrace.hh"
43 #include "debug/RubyPort.hh"
44 #include "debug/RubyStats.hh"
45 #include "gpu-compute/shader.hh"
46 #include "mem/packet.hh"
55 #include "params/RubyGPUCoalescer.hh"
56 
57 namespace gem5
58 {
59 
60 namespace ruby
61 {
62 
64  : coalescer(gc)
65 {
66 }
67 
68 void
70 {
71  uint64_t seqNum = pkt->req->getReqInstSeqNum();
72 
73  instMap[seqNum].push_back(pkt);
74  DPRINTF(GPUCoalescer, "Adding 0x%X seqNum %d to map. (map %d vec %d)\n",
75  pkt->getAddr(), seqNum, instMap.size(), instMap[seqNum].size());
76 }
77 
78 bool
80 {
81  return !instMap.empty();
82 }
83 
84 void
86 {
87  if (!instPktsRemaining.count(seqNum)) {
88  instPktsRemaining[seqNum] = count;
89  }
90 }
91 
92 int
94 {
95  return instPktsRemaining[seqNum];
96 }
97 
98 void
100 {
101  instPktsRemaining[seqNum] = count;
102 }
103 
106 {
107  if (offset >= instMap.size()) {
108  return nullptr;
109  }
110 
111  auto instMapIter = instMap.begin();
112  std::advance(instMapIter, offset);
113 
114  return &(instMapIter->second);
115 }
116 
117 void
119 {
120  for (auto iter = instMap.begin(); iter != instMap.end(); ) {
121  InstSeqNum seq_num = iter->first;
122  DPRINTF(GPUCoalescer, "%s checking remaining pkts for %d\n",
123  coalescer->name().c_str(), seq_num);
124  assert(instPktsRemaining.count(seq_num));
125 
126  if (instPktsRemaining[seq_num] == 0) {
127  assert(iter->second.empty());
128 
129  // Remove from both maps
130  instMap.erase(iter++);
131  instPktsRemaining.erase(seq_num);
132 
133  // Release the token
134  DPRINTF(GPUCoalescer, "Returning token seqNum %d\n", seq_num);
136  } else {
137  ++iter;
138  }
139  }
140 }
141 
142 bool
143 UncoalescedTable::areRequestsDone(const uint64_t instSeqNum) {
144  // iterate the instructions held in UncoalescedTable to see whether there
145  // are more requests to issue; if yes, not yet done; otherwise, done
146  for (auto& inst : instMap) {
147  DPRINTF(GPUCoalescer, "instSeqNum= %d, pending packets=%d\n"
148  ,inst.first, inst.second.size());
149  if (inst.first == instSeqNum) { return false; }
150  }
151 
152  return true;
153 }
154 
155 void
157 {
158  ss << "Listing pending packets from " << instMap.size() << " instructions";
159 
160  for (auto& inst : instMap) {
161  ss << "\tAddr: " << printAddress(inst.first) << " with "
162  << inst.second.size() << " pending packets" << std::endl;
163  }
164 }
165 
166 void
168 {
169  Tick current_time = curTick();
170 
171  for (auto &it : instMap) {
172  for (auto &pkt : it.second) {
173  if (current_time - pkt->req->time() > threshold) {
174  std::stringstream ss;
176 
177  panic("Possible Deadlock detected. Aborting!\n"
178  "version: %d request.paddr: 0x%x uncoalescedTable: %d "
179  "current time: %u issue_time: %d difference: %d\n"
180  "Request Tables:\n\n%s", coalescer->getId(),
181  pkt->getAddr(), instMap.size(), current_time,
182  pkt->req->time(), current_time - pkt->req->time(),
183  ss.str());
184  }
185  }
186  }
187 }
188 
190  : RubyPort(p),
191  issueEvent([this]{ completeIssue(); }, "Issue coalesced request",
193  uncoalescedTable(this),
194  deadlockCheckEvent([this]{ wakeup(); }, "GPUCoalescer deadlock check"),
195  gmTokenPort(name() + ".gmTokenPort", this)
196 {
197  m_store_waiting_on_load_cycles = 0;
198  m_store_waiting_on_store_cycles = 0;
199  m_load_waiting_on_store_cycles = 0;
200  m_load_waiting_on_load_cycles = 0;
201 
202  m_outstanding_count = 0;
203 
204  coalescingWindow = p.max_coalesces_per_cycle;
205 
206  m_max_outstanding_requests = 0;
207  m_instCache_ptr = nullptr;
208  m_dataCache_ptr = nullptr;
209 
210  m_instCache_ptr = p.icache;
211  m_dataCache_ptr = p.dcache;
212  m_max_outstanding_requests = p.max_outstanding_requests;
213  m_deadlock_threshold = p.deadlock_threshold;
214 
215  assert(m_max_outstanding_requests > 0);
216  assert(m_deadlock_threshold > 0);
217  assert(m_instCache_ptr);
218  assert(m_dataCache_ptr);
219 
220  m_runningGarnetStandalone = p.garnet_standalone;
221 
222 
223  // These statistical variables are not for display.
224  // The profiler will collate these across different
225  // coalescers and display those collated statistics.
226  m_outstandReqHist.init(10);
227  m_latencyHist.init(10);
228  m_missLatencyHist.init(10);
229 
230  for (int i = 0; i < RubyRequestType_NUM; i++) {
231  m_typeLatencyHist.push_back(new statistics::Histogram());
232  m_typeLatencyHist[i]->init(10);
233 
234  m_missTypeLatencyHist.push_back(new statistics::Histogram());
235  m_missTypeLatencyHist[i]->init(10);
236  }
237 
238  for (int i = 0; i < MachineType_NUM; i++) {
239  m_missMachLatencyHist.push_back(new statistics::Histogram());
240  m_missMachLatencyHist[i]->init(10);
241 
242  m_IssueToInitialDelayHist.push_back(new statistics::Histogram());
243  m_IssueToInitialDelayHist[i]->init(10);
244 
245  m_InitialToForwardDelayHist.push_back(new statistics::Histogram());
246  m_InitialToForwardDelayHist[i]->init(10);
247 
248  m_ForwardToFirstResponseDelayHist.push_back(
249  new statistics::Histogram());
250  m_ForwardToFirstResponseDelayHist[i]->init(10);
251 
252  m_FirstResponseToCompletionDelayHist.push_back(
253  new statistics::Histogram());
254  m_FirstResponseToCompletionDelayHist[i]->init(10);
255  }
256 
257  for (int i = 0; i < RubyRequestType_NUM; i++) {
258  m_missTypeMachLatencyHist.push_back(
260 
261  for (int j = 0; j < MachineType_NUM; j++) {
262  m_missTypeMachLatencyHist[i].push_back(
263  new statistics::Histogram());
264  m_missTypeMachLatencyHist[i][j]->init(10);
265  }
266  }
267 
268 }
269 
271 {
272 }
273 
274 Port &
275 GPUCoalescer::getPort(const std::string &if_name, PortID idx)
276 {
277  if (if_name == "gmTokenPort") {
278  return gmTokenPort;
279  }
280 
281  // delgate to RubyPort otherwise
282  return RubyPort::getPort(if_name, idx);
283 }
284 
285 void
287 {
288  Cycles current_time = curCycle();
289  for (auto& requestList : coalescedTable) {
290  for (auto& req : requestList.second) {
291  if (current_time - req->getIssueTime() > m_deadlock_threshold) {
292  std::stringstream ss;
294  warn("GPUCoalescer %d Possible deadlock detected!\n%s\n",
295  m_version, ss.str());
296  panic("Aborting due to deadlock!\n");
297  }
298  }
299  }
300 
301  Tick tick_threshold = cyclesToTicks(m_deadlock_threshold);
302  uncoalescedTable.checkDeadlock(tick_threshold);
303 
304  if (m_outstanding_count > 0) {
307  curTick());
308  }
309 }
310 
311 void
313 {
314  ss << "Printing out " << coalescedTable.size()
315  << " outstanding requests in the coalesced table\n";
316 
317  for (auto& requestList : coalescedTable) {
318  for (auto& request : requestList.second) {
319  ss << "\tAddr: " << printAddress(requestList.first) << "\n"
320  << "\tInstruction sequence number: "
321  << request->getSeqNum() << "\n"
322  << "\t\tType: "
323  << RubyRequestType_to_string(request->getRubyType()) << "\n"
324  << "\t\tNumber of associated packets: "
325  << request->getPackets().size() << "\n"
326  << "\t\tIssue time: "
327  << request->getIssueTime() * clockPeriod() << "\n"
328  << "\t\tDifference from current tick: "
329  << (curCycle() - request->getIssueTime()) * clockPeriod();
330  }
331  }
332 
333  // print out packets waiting to be issued in uncoalesced table
335 }
336 
337 void
339 {
342  for (int i = 0; i < RubyRequestType_NUM; i++) {
343  m_typeLatencyHist[i]->reset();
344  m_missTypeLatencyHist[i]->reset();
345  for (int j = 0; j < MachineType_NUM; j++) {
346  m_missTypeMachLatencyHist[i][j]->reset();
347  }
348  }
349 
350  for (int i = 0; i < MachineType_NUM; i++) {
351  m_missMachLatencyHist[i]->reset();
352 
353  m_IssueToInitialDelayHist[i]->reset();
354  m_InitialToForwardDelayHist[i]->reset();
357  }
358 }
359 
360 void
361 GPUCoalescer::printProgress(std::ostream& out) const
362 {
363 }
364 
365 // sets the kernelEndList
366 void
367 GPUCoalescer::insertKernel(int wavefront_id, PacketPtr pkt)
368 {
369  // Don't know if this will happen or is possible
370  // but I just want to be careful and not have it become
371  // simulator hang in the future
372  DPRINTF(GPUCoalescer, "inserting wf: %d to kernelEndlist\n", wavefront_id);
373  assert(kernelEndList.count(wavefront_id) == 0);
374 
375  kernelEndList[wavefront_id] = pkt;
376  DPRINTF(GPUCoalescer, "kernelEndList->size() = %d\n",
377  kernelEndList.size());
378 }
379 
380 void
382 {
383  writeCallback(address, MachineType_NULL, data);
384 }
385 
386 void
388  MachineType mach,
389  DataBlock& data)
390 {
391  writeCallback(address, mach, data, Cycles(0), Cycles(0), Cycles(0));
392 }
393 
394 void
396  MachineType mach,
397  DataBlock& data,
398  Cycles initialRequestTime,
399  Cycles forwardRequestTime,
400  Cycles firstResponseTime)
401 {
402  writeCallback(address, mach, data,
403  initialRequestTime, forwardRequestTime, firstResponseTime,
404  false);
405 }
406 
407 void
409  MachineType mach,
410  DataBlock& data,
411  Cycles initialRequestTime,
412  Cycles forwardRequestTime,
413  Cycles firstResponseTime,
414  bool isRegion)
415 {
416  assert(address == makeLineAddress(address));
417  assert(coalescedTable.count(address));
418 
419  auto crequest = coalescedTable.at(address).front();
420 
421  hitCallback(crequest, mach, data, true, crequest->getIssueTime(),
422  forwardRequestTime, firstResponseTime, isRegion);
423 
424  // remove this crequest in coalescedTable
425  delete crequest;
426  coalescedTable.at(address).pop_front();
427 
428  if (coalescedTable.at(address).empty()) {
429  coalescedTable.erase(address);
430  } else {
431  auto nextRequest = coalescedTable.at(address).front();
432  issueRequest(nextRequest);
433  }
434 }
435 
436 void
438  uint64_t instSeqNum,
439  MachineType mach)
440 {
441  DPRINTF(GPUCoalescer, "writeCompleteCallback for address 0x%x"
442  " instSeqNum = %d\n", address, instSeqNum);
443 
444  assert(pendingWriteInsts.count(instSeqNum) == 1);
445  PendingWriteInst& inst = pendingWriteInsts[instSeqNum];
446 
447  // check the uncoalescedTable to see whether all requests for the inst
448  // have been issued or not
449  bool reqsAllIssued = uncoalescedTable.areRequestsDone(instSeqNum);
450  DPRINTF(GPUCoalescer, "instSeqNum = %d, pendingStores=%d, "
451  "reqsAllIssued=%d\n", reqsAllIssued,
452  inst.getNumPendingStores()-1, reqsAllIssued);
453 
454  if (inst.receiveWriteCompleteAck() && reqsAllIssued ) {
455  // if the pending write instruction has received all write completion
456  // callbacks for its issued Ruby requests, we can now start respond
457  // the requesting CU in one response packet.
459 
460  DPRINTF(GPUCoalescer, "write inst %d completed at coalescer\n",
461  instSeqNum);
462  pendingWriteInsts.erase(instSeqNum);
463  }
464 }
465 
466 void
468 {
469  readCallback(address, MachineType_NULL, data);
470 }
471 
472 void
474  MachineType mach,
475  DataBlock& data)
476 {
477  readCallback(address, mach, data, Cycles(0), Cycles(0), Cycles(0));
478 }
479 
480 void
482  MachineType mach,
483  DataBlock& data,
484  Cycles initialRequestTime,
485  Cycles forwardRequestTime,
486  Cycles firstResponseTime)
487 {
488 
489  readCallback(address, mach, data,
490  initialRequestTime, forwardRequestTime, firstResponseTime,
491  false);
492 }
493 
494 void
496  MachineType mach,
497  DataBlock& data,
498  Cycles initialRequestTime,
499  Cycles forwardRequestTime,
500  Cycles firstResponseTime,
501  bool isRegion)
502 {
503  assert(address == makeLineAddress(address));
504  assert(coalescedTable.count(address));
505 
506  auto crequest = coalescedTable.at(address).front();
507  fatal_if(crequest->getRubyType() != RubyRequestType_LD,
508  "readCallback received non-read type response\n");
509 
510  // Iterate over the coalesced requests to respond to as many loads as
511  // possible until another request type is seen. Models MSHR for TCP.
512  while (crequest->getRubyType() == RubyRequestType_LD) {
513  hitCallback(crequest, mach, data, true, crequest->getIssueTime(),
514  forwardRequestTime, firstResponseTime, isRegion);
515 
516  delete crequest;
517  coalescedTable.at(address).pop_front();
518  if (coalescedTable.at(address).empty()) {
519  break;
520  }
521 
522  crequest = coalescedTable.at(address).front();
523  }
524 
525  if (coalescedTable.at(address).empty()) {
526  coalescedTable.erase(address);
527  } else {
528  auto nextRequest = coalescedTable.at(address).front();
529  issueRequest(nextRequest);
530  }
531 }
532 
533 void
535  MachineType mach,
536  DataBlock& data,
537  bool success,
538  Cycles initialRequestTime,
539  Cycles forwardRequestTime,
540  Cycles firstResponseTime,
541  bool isRegion)
542 {
543  PacketPtr pkt = crequest->getFirstPkt();
544  Addr request_address = pkt->getAddr();
545  GEM5_VAR_USED Addr request_line_address = makeLineAddress(request_address);
546 
547  RubyRequestType type = crequest->getRubyType();
548 
549  DPRINTF(GPUCoalescer, "Got hitCallback for 0x%X\n", request_line_address);
550 
551  recordMissLatency(crequest, mach,
552  initialRequestTime,
553  forwardRequestTime,
554  firstResponseTime,
555  success, isRegion);
556  // update the data
557  //
558  // MUST AD DOING THIS FOR EACH REQUEST IN COALESCER
559  std::vector<PacketPtr> pktList = crequest->getPackets();
560  DPRINTF(GPUCoalescer, "Responding to %d packets for addr 0x%X\n",
561  pktList.size(), request_line_address);
562  for (auto& pkt : pktList) {
563  request_address = pkt->getAddr();
564  if (pkt->getPtr<uint8_t>()) {
565  if ((type == RubyRequestType_LD) ||
566  (type == RubyRequestType_ATOMIC) ||
567  (type == RubyRequestType_ATOMIC_RETURN) ||
568  (type == RubyRequestType_IFETCH) ||
569  (type == RubyRequestType_RMW_Read) ||
570  (type == RubyRequestType_Locked_RMW_Read) ||
571  (type == RubyRequestType_Load_Linked)) {
572  pkt->setData(
573  data.getData(getOffset(request_address), pkt->getSize()));
574  } else {
575  data.setData(pkt->getPtr<uint8_t>(),
576  getOffset(request_address), pkt->getSize());
577  }
578  } else {
579  DPRINTF(MemoryAccess,
580  "WARNING. Data not transfered from Ruby to M5 for type " \
581  "%s\n",
582  RubyRequestType_to_string(type));
583  }
584  }
585 
587  assert(m_outstanding_count >= 0);
588 
589  completeHitCallback(pktList);
590 }
591 
592 bool
594 {
595  return coalescedTable.empty();
596 }
597 
598 RubyRequestType
600 {
601  RubyRequestType req_type = RubyRequestType_NULL;
602 
603  // These types are not support or not used in GPU caches.
604  assert(!pkt->req->isLLSC());
605  assert(!pkt->req->isLockedRMW());
606  assert(!pkt->req->isInstFetch());
607  assert(!pkt->isFlush());
608 
609  if (pkt->req->isAtomicReturn()) {
610  req_type = RubyRequestType_ATOMIC_RETURN;
611  } else if (pkt->req->isAtomicNoReturn()) {
612  req_type = RubyRequestType_ATOMIC_NO_RETURN;
613  } else if (pkt->isRead()) {
614  req_type = RubyRequestType_LD;
615  } else if (pkt->isWrite()) {
616  req_type = RubyRequestType_ST;
617  } else {
618  panic("Unsupported ruby packet type\n");
619  }
620 
621  return req_type;
622 }
623 
624 // Places an uncoalesced packet in uncoalescedTable. If the packet is a
625 // special type (MemFence, scoping, etc), it is issued immediately.
626 RequestStatus
628 {
629  // all packets must have valid instruction sequence numbers
630  assert(pkt->req->hasInstSeqNum());
631 
632  if (pkt->cmd == MemCmd::MemSyncReq) {
633  // issue mem_sync requests immediately to the cache system without
634  // going through uncoalescedTable like normal LD/ST/Atomic requests
635  issueMemSyncRequest(pkt);
636  } else {
637  // otherwise, this must be either read or write command
638  assert(pkt->isRead() || pkt->isWrite());
639 
640  InstSeqNum seq_num = pkt->req->getReqInstSeqNum();
641 
642  // in the case of protocol tester, there is one packet per sequence
643  // number. The number of packets during simulation depends on the
644  // number of lanes actives for that vmem request (i.e., the popcnt
645  // of the exec_mask.
646  int num_packets = 1;
647  if (!m_usingRubyTester) {
648  num_packets = 0;
649  for (int i = 0; i < TheGpuISA::NumVecElemPerVecReg; i++) {
650  num_packets += getDynInst(pkt)->getLaneStatus(i);
651  }
652  }
653 
654  // the pkt is temporarily stored in the uncoalesced table until
655  // it's picked for coalescing process later in this cycle or in a
656  // future cycle. Packets remaining is set to the number of excepted
657  // requests from the instruction based on its exec_mask.
659  uncoalescedTable.initPacketsRemaining(seq_num, num_packets);
660  DPRINTF(GPUCoalescer, "Put pkt with addr 0x%X to uncoalescedTable\n",
661  pkt->getAddr());
662 
663  // we schedule an issue event here to process the uncoalesced table
664  // and try to issue Ruby request to cache system
665  if (!issueEvent.scheduled()) {
666  DPRINTF(GPUCoalescer, "Scheduled issueEvent for seqNum %d\n",
667  seq_num);
669  }
670  }
671 
672  // we always return RequestStatus_Issued in this coalescer
673  // b/c the coalescer's resouce was checked ealier and the coalescer is
674  // queueing up aliased requets in its coalesced table
675  return RequestStatus_Issued;
676 }
677 
678 template <class KEY, class VALUE>
679 std::ostream &
680 operator<<(std::ostream &out, const std::unordered_map<KEY, VALUE> &map)
681 {
682  out << "[";
683  for (auto i = map.begin(); i != map.end(); ++i)
684  out << " " << i->first << "=" << i->second;
685  out << " ]";
686 
687  return out;
688 }
689 
690 void
691 GPUCoalescer::print(std::ostream& out) const
692 {
693  out << "[GPUCoalescer: " << m_version
694  << ", outstanding requests: " << m_outstanding_count
695  << "]";
696 }
697 
700 {
702  safe_cast<RubyPort::SenderState*>(pkt->senderState);
703 
705  safe_cast<ComputeUnit::DataPort::SenderState*>
706  (ss->predecessor);
707 
708  return cu_state->_gpuDynInst;
709 }
710 
711 bool
713 {
714  uint64_t seqNum = pkt->req->getReqInstSeqNum();
715  Addr line_addr = makeLineAddress(pkt->getAddr());
716 
717  // If the packet has the same line address as a request already in the
718  // coalescedTable and has the same sequence number, it can be coalesced.
719  if (coalescedTable.count(line_addr)) {
720  // Search for a previous coalesced request with the same seqNum.
721  auto& creqQueue = coalescedTable.at(line_addr);
722  auto citer = std::find_if(creqQueue.begin(), creqQueue.end(),
723  [&](CoalescedRequest* c) { return c->getSeqNum() == seqNum; }
724  );
725  if (citer != creqQueue.end()) {
726  (*citer)->insertPacket(pkt);
727  return true;
728  }
729  }
730 
732  // This is an "aliased" or new request. Create a RubyRequest and
733  // append it to the list of "targets" in the coalescing table.
734  DPRINTF(GPUCoalescer, "Creating new or aliased request for 0x%X\n",
735  line_addr);
736 
737  CoalescedRequest *creq = new CoalescedRequest(seqNum);
738  creq->insertPacket(pkt);
739  creq->setRubyType(getRequestType(pkt));
740  creq->setIssueTime(curCycle());
741 
742  if (!coalescedTable.count(line_addr)) {
743  // If there is no outstanding request for this line address,
744  // create a new coalecsed request and issue it immediately.
745  auto reqList = std::deque<CoalescedRequest*> { creq };
746  coalescedTable.insert(std::make_pair(line_addr, reqList));
747  if (!coalescedReqs.count(seqNum)) {
748  coalescedReqs.insert(std::make_pair(seqNum, reqList));
749  } else {
750  coalescedReqs.at(seqNum).push_back(creq);
751  }
752  } else {
753  // The request is for a line address that is already outstanding
754  // but for a different instruction. Add it as a new request to be
755  // issued when the current outstanding request is completed.
756  coalescedTable.at(line_addr).push_back(creq);
757  DPRINTF(GPUCoalescer, "found address 0x%X with new seqNum %d\n",
758  line_addr, seqNum);
759  }
760 
761  // In both cases, requests are added to the coalescing table and will
762  // be counted as outstanding requests.
764 
765  // We track all issued or to-be-issued Ruby requests associated with
766  // write instructions. An instruction may have multiple Ruby
767  // requests.
768  if (pkt->cmd == MemCmd::WriteReq) {
769  DPRINTF(GPUCoalescer, "adding write inst %d at line 0x%x to"
770  " the pending write instruction list\n", seqNum,
771  line_addr);
772 
774  safe_cast<RubyPort::SenderState*>(pkt->senderState);
775 
776  // we need to save this port because it will be used to call
777  // back the requesting CU when we receive write
778  // complete callbacks for all issued Ruby requests of this
779  // instruction.
780  RubyPort::MemResponsePort* mem_response_port = ss->port;
781 
782  GPUDynInstPtr gpuDynInst = nullptr;
783 
784  if (!m_usingRubyTester) {
785  // If this coalescer is connected to a real CU, we need
786  // to save the corresponding gpu dynamic instruction.
787  // CU will use that instruction to decrement wait counters
788  // in the issuing wavefront.
789  // For Ruby tester, gpuDynInst == nullptr
790  gpuDynInst = getDynInst(pkt);
791  }
792 
793  PendingWriteInst& inst = pendingWriteInsts[seqNum];
794  inst.addPendingReq(mem_response_port, gpuDynInst,
796  }
797 
798  return true;
799  }
800 
801  // The maximum number of outstanding requests have been issued.
802  return false;
803 }
804 
805 void
807 {
808  // Iterate over the maximum number of instructions we can coalesce
809  // per cycle (coalescingWindow).
810  for (int instIdx = 0; instIdx < coalescingWindow; ++instIdx) {
811  PerInstPackets *pkt_list =
813 
814  // getInstPackets will return nullptr if no instruction
815  // exists at the current offset.
816  if (!pkt_list) {
817  break;
818  } else if (pkt_list->empty()) {
819  // Found something, but it has not been cleaned up by update
820  // resources yet. See if there is anything else to coalesce.
821  // Assume we can't check anymore if the coalescing window is 1.
822  continue;
823  } else {
824  // All packets in the list have the same seqNum, use first.
825  InstSeqNum seq_num = pkt_list->front()->req->getReqInstSeqNum();
826 
827  // The difference in list size before and after tells us the
828  // number of packets which were coalesced.
829  size_t pkt_list_size = pkt_list->size();
830 
831  // Since we have a pointer to the list of packets in the inst,
832  // erase them from the list if coalescing is successful and
833  // leave them in the list otherwise. This aggressively attempts
834  // to coalesce as many packets as possible from the current inst.
835  pkt_list->remove_if(
836  [&](PacketPtr pkt) { return coalescePacket(pkt); }
837  );
838 
839  if (coalescedReqs.count(seq_num)) {
840  auto& creqs = coalescedReqs.at(seq_num);
841  for (auto creq : creqs) {
842  DPRINTF(GPUCoalescer, "Issued req type %s seqNum %d\n",
843  RubyRequestType_to_string(creq->getRubyType()),
844  seq_num);
845  issueRequest(creq);
846  }
847  coalescedReqs.erase(seq_num);
848  }
849 
850  assert(pkt_list_size >= pkt_list->size());
851  size_t pkt_list_diff = pkt_list_size - pkt_list->size();
852 
853  int num_remaining = uncoalescedTable.getPacketsRemaining(seq_num);
854  num_remaining -= pkt_list_diff;
855  assert(num_remaining >= 0);
856 
857  uncoalescedTable.setPacketsRemaining(seq_num, num_remaining);
859  "Coalesced %d pkts for seqNum %d, %d remaining\n",
860  pkt_list_diff, seq_num, num_remaining);
861  }
862  }
863 
864  // Clean up any instructions in the uncoalesced table that have had
865  // all of their packets coalesced and return a token for that column.
867 
868  // have Kernel End releases been issued this cycle
869  int len = newKernelEnds.size();
870  for (int i = 0; i < len; i++) {
872  }
873  newKernelEnds.clear();
874 }
875 
876 void
878 {
879  ruby_eviction_callback(address);
880 }
881 
882 void
884 {
885  assert(kernelEndList.count(wavefront_id));
886 
887  ruby_hit_callback(kernelEndList[wavefront_id]);
888 
889  kernelEndList.erase(wavefront_id);
890 }
891 
892 void
894  MachineType mach,
895  const DataBlock& data)
896 {
897  assert(address == makeLineAddress(address));
898  assert(coalescedTable.count(address));
899 
900  auto crequest = coalescedTable.at(address).front();
901 
902  fatal_if((crequest->getRubyType() != RubyRequestType_ATOMIC &&
903  crequest->getRubyType() != RubyRequestType_ATOMIC_RETURN &&
904  crequest->getRubyType() != RubyRequestType_ATOMIC_NO_RETURN),
905  "atomicCallback saw non-atomic type response\n");
906 
907  hitCallback(crequest, mach, (DataBlock&)data, true,
908  crequest->getIssueTime(), Cycles(0), Cycles(0), false);
909 
910  delete crequest;
911  coalescedTable.at(address).pop_front();
912 
913  if (coalescedTable.at(address).empty()) {
914  coalescedTable.erase(address);
915  } else {
916  auto nextRequest = coalescedTable.at(address).front();
917  issueRequest(nextRequest);
918  }
919 }
920 
921 void
923 {
924  for (auto& pkt : mylist) {
926  safe_cast<RubyPort::SenderState *>(pkt->senderState);
927  MemResponsePort *port = ss->port;
928  assert(port != NULL);
929 
930  pkt->senderState = ss->predecessor;
931 
932  if (pkt->cmd != MemCmd::WriteReq) {
933  // for WriteReq, we keep the original senderState until
934  // writeCompleteCallback
935  delete ss;
936  }
937 
938  port->hitCallback(pkt);
939  trySendRetries();
940  }
941 
942  // We schedule an event in the same tick as hitCallback (similar to
943  // makeRequest) rather than calling completeIssue directly to reduce
944  // function calls to complete issue. This can only happen if the max
945  // outstanding requests is less than the number of slots in the
946  // uncoalesced table and makeRequest is not called again.
949  }
950 
952 }
953 
954 void
956  MachineType mach,
957  Cycles initialRequestTime,
958  Cycles forwardRequestTime,
959  Cycles firstResponseTime,
960  bool success, bool isRegion)
961 {
962 }
963 
964 } // namespace ruby
965 } // namespace gem5
gem5::ruby::GPUCoalescer::getRequestType
virtual RubyRequestType getRequestType(PacketPtr pkt)
Definition: GPUCoalescer.cc:599
gem5::ruby::GPUCoalescer::printRequestTable
void printRequestTable(std::stringstream &ss)
Definition: GPUCoalescer.cc:312
gem5::ruby::GPUCoalescer::kernelEndList
std::unordered_map< int, PacketPtr > kernelEndList
Definition: GPUCoalescer.hh:451
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:252
gem5::ArmISA::NumVecElemPerVecReg
constexpr unsigned NumVecElemPerVecReg
Definition: vec.hh:58
gem5::ruby::CoalescedRequest::setIssueTime
void setIssueTime(Cycles _issueTime)
Definition: GPUCoalescer.hh:119
gem5::ruby::RubyPort::m_version
uint32_t m_version
Definition: RubyPort.hh:196
gem5::ruby::RubyPort::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: RubyPort.cc:101
gem5::ArmISA::len
Bitfield< 18, 16 > len
Definition: misc_types.hh:444
gem5::ruby::GPUCoalescer::pendingWriteInsts
std::unordered_map< uint64_t, PendingWriteInst > pendingWriteInsts
Definition: GPUCoalescer.hh:446
warn
#define warn(...)
Definition: logging.hh:245
Profiler.hh
data
const char data[]
Definition: circlebuf.test.cc:48
shader.hh
gem5::Clocked::curCycle
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Definition: clocked_object.hh:195
gem5::ruby::printAddress
std::string printAddress(Addr addr)
Definition: Address.cc:80
gem5::ruby::PendingWriteInst::ackWriteCompletion
void ackWriteCompletion(bool usingRubyTester)
Definition: GPUCoalescer.hh:176
gem5::ruby::GPUCoalescer::m_typeLatencyHist
std::vector< statistics::Histogram * > m_typeLatencyHist
Definition: GPUCoalescer.hh:492
gem5::ruby::GPUCoalescer::coalescedTable
std::map< Addr, std::deque< CoalescedRequest * > > coalescedTable
Definition: GPUCoalescer.hh:437
gem5::ruby::UncoalescedTable::packetAvailable
bool packetAvailable()
Definition: GPUCoalescer.cc:79
gem5::ruby::PendingWriteInst::getNumPendingStores
int getNumPendingStores()
Definition: GPUCoalescer.hh:197
gem5::Packet::setData
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
Definition: packet.hh:1252
gem5::ruby::GPUCoalescer::m_missTypeLatencyHist
std::vector< statistics::Histogram * > m_missTypeLatencyHist
Definition: GPUCoalescer.hh:497
gem5::ruby::operator<<
std::ostream & operator<<(std::ostream &os, const BoolVec &myvector)
Definition: BoolVec.cc:49
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:366
gem5::ruby::GPUCoalescer::issueMemSyncRequest
virtual void issueMemSyncRequest(PacketPtr pkt)
Definition: GPUCoalescer.hh:383
gem5::ruby::UncoalescedTable::setPacketsRemaining
void setPacketsRemaining(InstSeqNum seqNum, int count)
Definition: GPUCoalescer.cc:99
gem5::ruby::RubyPort::MemResponsePort
Definition: RubyPort.hh:81
gem5::ruby::GPUCoalescer::coalescePacket
bool coalescePacket(PacketPtr pkt)
Definition: GPUCoalescer.cc:712
gem5::ruby::GPUCoalescer::wakeup
void wakeup()
Definition: GPUCoalescer.cc:286
GPUCoalescer.hh
AbstractController.hh
gem5::ruby::GPUCoalescer::newKernelEnds
std::vector< int > newKernelEnds
Definition: GPUCoalescer.hh:452
gem5::ruby::RubyPort::ruby_hit_callback
void ruby_hit_callback(PacketPtr pkt)
Definition: RubyPort.cc:441
gem5::Packet::isWrite
bool isWrite() const
Definition: packet.hh:583
gem5::ruby::UncoalescedTable::instMap
std::map< InstSeqNum, PerInstPackets > instMap
Definition: GPUCoalescer.hh:103
gem5::ruby::GPUCoalescer::getDynInst
GPUDynInstPtr getDynInst(PacketPtr pkt) const
Definition: GPUCoalescer.cc:699
RubyRequest.hh
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
std::vector
STL vector class.
Definition: stl.hh:37
gem5::ruby::GPUCoalescer::writeCallback
void writeCallback(Addr address, DataBlock &data)
Definition: GPUCoalescer.cc:381
gem5::ruby::RubyPort::trySendRetries
void trySendRetries()
Definition: RubyPort.cc:464
gem5::ruby::PendingWriteInst::receiveWriteCompleteAck
bool receiveWriteCompleteAck()
Definition: GPUCoalescer.hh:167
gem5::ruby::CoalescedRequest::setRubyType
void setRubyType(RubyRequestType type)
Definition: GPUCoalescer.hh:120
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::ruby::makeLineAddress
Addr makeLineAddress(Addr addr)
Definition: Address.cc:60
gem5::ruby::RubyPort::SenderState
Definition: RubyPort.hh:146
gem5::ruby::RubyPort::MemResponsePort::hitCallback
void hitCallback(PacketPtr pkt)
Definition: RubyPort.cc:524
gem5::ruby::GPUCoalescer::m_IssueToInitialDelayHist
std::vector< statistics::Histogram * > m_IssueToInitialDelayHist
Histograms for recording the breakdown of miss latency.
Definition: GPUCoalescer.hh:506
gem5::EventBase::Progress_Event_Pri
static const Priority Progress_Event_Pri
Progress events come at the end.
Definition: eventq.hh:226
gem5::ruby::GPUCoalescer::evictionCallback
void evictionCallback(Addr address)
Definition: GPUCoalescer.cc:877
gem5::ruby::UncoalescedTable::instPktsRemaining
std::map< InstSeqNum, int > instPktsRemaining
Definition: GPUCoalescer.hh:105
packet.hh
gem5::ruby::CoalescedRequest::getFirstPkt
PacketPtr getFirstPkt() const
Definition: GPUCoalescer.hh:123
gem5::ruby::GPUCoalescer::printProgress
void printProgress(std::ostream &out) const
Definition: GPUCoalescer.cc:361
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
str.hh
gem5::ruby::GPUCoalescer::~GPUCoalescer
~GPUCoalescer()
Definition: GPUCoalescer.cc:270
gem5::ruby::GPUCoalescer::getGMTokenPort
GMTokenPort & getGMTokenPort()
Definition: GPUCoalescer.hh:340
gem5::statistics::Histogram
A simple histogram stat.
Definition: statistics.hh:2123
gem5::ruby::GPUCoalescer::m_latencyHist
statistics::Histogram m_latencyHist
Histogram for holding latency profile of all requests.
Definition: GPUCoalescer.hh:491
gem5::ruby::GPUCoalescer::issueRequest
virtual void issueRequest(CoalescedRequest *crequest)=0
gem5::ruby::UncoalescedTable::getInstPackets
PerInstPackets * getInstPackets(int offset)
Definition: GPUCoalescer.cc:105
gem5::ArmISA::j
Bitfield< 24 > j
Definition: misc_types.hh:57
gem5::ruby::RubyPort::m_usingRubyTester
bool m_usingRubyTester
Definition: RubyPort.hh:199
gem5::Packet::isRead
bool isRead() const
Definition: packet.hh:582
gem5::ruby::RubyPort::ruby_eviction_callback
void ruby_eviction_callback(Addr address)
Definition: RubyPort.cc:640
gem5::ruby::GPUCoalescer::recordMissLatency
void recordMissLatency(CoalescedRequest *crequest, MachineType mach, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime, bool success, bool isRegion)
Definition: GPUCoalescer.cc:955
CacheMemory.hh
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::ruby::PendingWriteInst::addPendingReq
void addPendingReq(RubyPort::MemResponsePort *port, GPUDynInstPtr inst, bool usingRubyTester)
Definition: GPUCoalescer.hh:152
gem5::Clocked::cyclesToTicks
Tick cyclesToTicks(Cycles c) const
Definition: clocked_object.hh:227
gem5::ruby::GPUCoalescer::Params
RubyGPUCoalescerParams Params
Definition: GPUCoalescer.hh:238
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::X86ISA::count
count
Definition: misc.hh:709
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
DataBlock.hh
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::ruby::UncoalescedTable::updateResources
void updateResources()
Definition: GPUCoalescer.cc:118
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::X86ISA::type
type
Definition: misc.hh:733
gem5::ruby::GPUCoalescer::gmTokenPort
GMTokenPort gmTokenPort
Definition: GPUCoalescer.hh:530
RubyTester.hh
gem5::ruby::CoalescedRequest::getPackets
std::vector< PacketPtr > & getPackets()
Definition: GPUCoalescer.hh:126
gem5::MemCmd::MemSyncReq
@ MemSyncReq
Definition: packet.hh:119
gem5::ruby::GPUCoalescer::m_deadlock_threshold
Cycles m_deadlock_threshold
Definition: GPUCoalescer.hh:418
gem5::ruby::GPUCoalescer::completeIssue
void completeIssue()
Definition: GPUCoalescer.cc:806
gem5::ruby::getOffset
Addr getOffset(Addr addr)
Definition: Address.cc:54
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::ruby::GPUCoalescer::m_InitialToForwardDelayHist
std::vector< statistics::Histogram * > m_InitialToForwardDelayHist
Definition: GPUCoalescer.hh:507
ss
std::stringstream ss
Definition: trace.test.cc:45
compiler.hh
gem5::ruby::GPUCoalescer::empty
bool empty() const
Definition: GPUCoalescer.cc:593
gem5::ruby::GPUCoalescer::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: GPUCoalescer.cc:275
gem5::ruby::GPUCoalescer::coalescedReqs
std::unordered_map< uint64_t, std::deque< CoalescedRequest * > > coalescedReqs
Definition: GPUCoalescer.hh:441
gem5::ruby::UncoalescedTable::checkDeadlock
void checkDeadlock(Tick threshold)
Definition: GPUCoalescer.cc:167
gem5::ComputeUnit::DataPort::SenderState::_gpuDynInst
GPUDynInstPtr _gpuDynInst
Definition: compute_unit.hh:520
gem5::ruby::UncoalescedTable::UncoalescedTable
UncoalescedTable(GPUCoalescer *gc)
Definition: GPUCoalescer.cc:63
gem5::ruby::GPUCoalescer::completeHitCallback
void completeHitCallback(std::vector< PacketPtr > &mylist)
Definition: GPUCoalescer.cc:922
gem5::Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:361
gem5::ArmISA::c
Bitfield< 29 > c
Definition: misc_types.hh:53
gem5::ruby::CoalescedRequest::insertPacket
void insertPacket(PacketPtr pkt)
Definition: GPUCoalescer.hh:117
RubySystem.hh
gem5::ruby::GPUCoalescer::issueEvent
EventFunctionWrapper issueEvent
Definition: GPUCoalescer.hh:414
gem5::ruby::RubyPort::testDrainComplete
void testDrainComplete()
Definition: RubyPort.cc:490
gem5::ruby::PendingWriteInst
Definition: GPUCoalescer.hh:139
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::ruby::GPUCoalescer::writeCompleteCallback
void writeCompleteCallback(Addr address, uint64_t instSeqNum, MachineType mach)
Definition: GPUCoalescer.cc:437
gem5::Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:534
gem5::ruby::GPUCoalescer::m_ForwardToFirstResponseDelayHist
std::vector< statistics::Histogram * > m_ForwardToFirstResponseDelayHist
Definition: GPUCoalescer.hh:508
name
const std::string & name()
Definition: trace.cc:49
gem5::GPUDynInstPtr
std::shared_ptr< GPUDynInst > GPUDynInstPtr
Definition: misc.hh:51
gem5::ruby::GPUCoalescer::GPUCoalescer
GPUCoalescer(const Params &)
Definition: GPUCoalescer.cc:189
gem5::ruby::GPUCoalescer::deadlockCheckEvent
EventFunctionWrapper deadlockCheckEvent
Definition: GPUCoalescer.hh:461
gem5::ruby::GPUCoalescer::resetStats
void resetStats() override
Callback to reset stats.
Definition: GPUCoalescer.cc:338
gem5::ruby::GPUCoalescer::hitCallback
void hitCallback(CoalescedRequest *crequest, MachineType mach, DataBlock &data, bool success, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime, bool isRegion)
Definition: GPUCoalescer.cc:534
MessageBuffer.hh
gem5::ruby::GPUCoalescer::readCallback
void readCallback(Addr address, DataBlock &data)
Definition: GPUCoalescer.cc:467
gem5::ruby::UncoalescedTable::initPacketsRemaining
void initPacketsRemaining(InstSeqNum seqNum, int count)
Definition: GPUCoalescer.cc:85
gem5::Packet::isFlush
bool isFlush() const
Definition: packet.hh:612
gem5::Port
Ports are used to interface objects to each other.
Definition: port.hh:61
gem5::TokenResponsePort::sendTokens
void sendTokens(int num_tokens)
Return num_tokens tokens back to the request port.
Definition: token_port.cc:80
gem5::ruby::GPUCoalescer::m_missTypeMachLatencyHist
std::vector< std::vector< statistics::Histogram * > > m_missTypeMachLatencyHist
Definition: GPUCoalescer.hh:503
gem5::ruby::UncoalescedTable::coalescer
GPUCoalescer * coalescer
Definition: GPUCoalescer.hh:97
gem5::ruby::CoalescedRequest
Definition: GPUCoalescer.hh:108
gem5::ruby::UncoalescedTable::printRequestTable
void printRequestTable(std::stringstream &ss)
Definition: GPUCoalescer.cc:156
gem5::ruby::GPUCoalescer::uncoalescedTable
UncoalescedTable uncoalescedTable
Definition: GPUCoalescer.hh:430
std::deque
STL deque class.
Definition: stl.hh:44
gem5::ruby::UncoalescedTable::areRequestsDone
bool areRequestsDone(const InstSeqNum instSeqNum)
Definition: GPUCoalescer.cc:143
gem5::ruby::GPUCoalescer::makeRequest
RequestStatus makeRequest(PacketPtr pkt) override
Definition: GPUCoalescer.cc:627
gem5::ruby::GPUCoalescer::kernelCallback
void kernelCallback(int wavefront_id)
Definition: GPUCoalescer.cc:883
gem5::MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:89
gem5::ruby::GPUCoalescer::m_missMachLatencyHist
std::vector< statistics::Histogram * > m_missMachLatencyHist
Histograms for profiling the latencies for requests that required external messages.
Definition: GPUCoalescer.hh:501
gem5::ruby::GPUCoalescer::m_missLatencyHist
statistics::Histogram m_missLatencyHist
Histogram for holding latency profile of all requests that miss in the controller connected to this s...
Definition: GPUCoalescer.hh:496
logging.hh
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::ruby::GPUCoalescer::atomicCallback
virtual void atomicCallback(Addr address, MachineType mach, const DataBlock &data)
Definition: GPUCoalescer.cc:893
gem5::ruby::GPUCoalescer::insertKernel
void insertKernel(int wavefront_id, PacketPtr pkt)
Definition: GPUCoalescer.cc:367
gem5::ruby::UncoalescedTable::getPacketsRemaining
int getPacketsRemaining(InstSeqNum seqNum)
Definition: GPUCoalescer.cc:93
gem5::statistics::DistBase::reset
void reset()
Reset stat value to default.
Definition: statistics.hh:1349
gem5::ruby::GPUCoalescer::m_max_outstanding_requests
int m_max_outstanding_requests
Definition: GPUCoalescer.hh:417
gem5::ruby::UncoalescedTable::insertPacket
void insertPacket(PacketPtr pkt)
Definition: GPUCoalescer.cc:69
gem5::ruby::DataBlock
Definition: DataBlock.hh:60
std::list
STL list class.
Definition: stl.hh:51
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
gem5::ruby::CoalescedRequest::getRubyType
RubyRequestType getRubyType() const
Definition: GPUCoalescer.hh:125
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
gem5::ruby::GPUCoalescer::m_outstanding_count
int m_outstanding_count
Definition: GPUCoalescer.hh:449
gem5::ruby::RubyPort
Definition: RubyPort.hh:64
gem5::ruby::GPUCoalescer::m_FirstResponseToCompletionDelayHist
std::vector< statistics::Histogram * > m_FirstResponseToCompletionDelayHist
Definition: GPUCoalescer.hh:509
gem5::ruby::GPUCoalescer::coalescingWindow
int coalescingWindow
Definition: GPUCoalescer.hh:425
gem5::ruby::GPUCoalescer::print
void print(std::ostream &out) const
Definition: GPUCoalescer.cc:691
SubBlock.hh
gem5::ruby::GPUCoalescer
Definition: GPUCoalescer.hh:215
gem5::ComputeUnit::DataPort::SenderState
Definition: compute_unit.hh:518
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:791
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::Clocked::clockPeriod
Tick clockPeriod() const
Definition: clocked_object.hh:217
gem5::ruby::RubyPort::getId
uint32_t getId()
Definition: RubyPort.hh:172
gem5::Packet::getPtr
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:1184

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