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"
55 #include "params/RubyGPUCoalescer.hh"
71 uint64_t seqNum = pkt->
req->getReqInstSeqNum();
111 auto instMapIter =
instMap.begin();
112 std::advance(instMapIter,
offset);
114 return &(instMapIter->second);
127 assert(iter->second.empty());
148 ,inst.first, inst.second.size());
149 if (inst.first == instSeqNum) {
return false; }
158 ss <<
"Listing pending packets from " <<
instMap.size() <<
" instructions";
162 << inst.second.size() <<
" pending packets" << std::endl;
172 for (
auto &pkt : it.second) {
173 if (current_time - pkt->req->time() > threshold) {
174 std::stringstream
ss;
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"
181 pkt->getAddr(),
instMap.size(), current_time,
182 pkt->req->time(), current_time - pkt->req->time(),
191 issueEvent([this]{
completeIssue(); },
"Issue coalesced request",
193 uncoalescedTable(
this),
194 deadlockCheckEvent([
this]{ wakeup(); },
"GPUCoalescer deadlock check"),
195 gmTokenPort(
name() +
".gmTokenPort",
this)
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;
202 m_outstanding_count = 0;
204 coalescingWindow =
p.max_coalesces_per_cycle;
206 m_max_outstanding_requests = 0;
207 m_instCache_ptr =
nullptr;
208 m_dataCache_ptr =
nullptr;
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;
215 assert(m_max_outstanding_requests > 0);
216 assert(m_deadlock_threshold > 0);
217 assert(m_instCache_ptr);
218 assert(m_dataCache_ptr);
220 m_runningGarnetStandalone =
p.garnet_standalone;
226 m_outstandReqHist.init(10);
227 m_latencyHist.init(10);
228 m_missLatencyHist.init(10);
230 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
232 m_typeLatencyHist[
i]->init(10);
235 m_missTypeLatencyHist[
i]->init(10);
238 for (
int i = 0;
i < MachineType_NUM;
i++) {
239 m_missMachLatencyHist.push_back(
new statistics::Histogram());
240 m_missMachLatencyHist[
i]->init(10);
242 m_IssueToInitialDelayHist.push_back(
new statistics::Histogram());
243 m_IssueToInitialDelayHist[
i]->init(10);
245 m_InitialToForwardDelayHist.push_back(
new statistics::Histogram());
246 m_InitialToForwardDelayHist[
i]->init(10);
248 m_ForwardToFirstResponseDelayHist.push_back(
249 new statistics::Histogram());
250 m_ForwardToFirstResponseDelayHist[
i]->init(10);
252 m_FirstResponseToCompletionDelayHist.push_back(
253 new statistics::Histogram());
254 m_FirstResponseToCompletionDelayHist[
i]->init(10);
257 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
258 m_missTypeMachLatencyHist.push_back(
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);
277 if (if_name ==
"gmTokenPort") {
290 for (
auto& req : requestList.second) {
292 std::stringstream
ss;
294 warn(
"GPUCoalescer %d Possible deadlock detected!\n%s\n",
296 panic(
"Aborting due to deadlock!\n");
315 <<
" outstanding requests in the coalesced table\n";
318 for (
auto& request : requestList.second) {
320 <<
"\tInstruction sequence number: "
321 << request->getSeqNum() <<
"\n"
323 << RubyRequestType_to_string(request->getRubyType()) <<
"\n"
324 <<
"\t\tNumber of associated packets: "
325 << request->getPackets().size() <<
"\n"
326 <<
"\t\tIssue time: "
328 <<
"\t\tDifference from current tick: "
342 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
345 for (
int j = 0;
j < MachineType_NUM;
j++) {
350 for (
int i = 0;
i < MachineType_NUM;
i++) {
398 Cycles initialRequestTime,
399 Cycles forwardRequestTime,
403 initialRequestTime, forwardRequestTime, firstResponseTime,
411 Cycles initialRequestTime,
412 Cycles forwardRequestTime,
422 forwardRequestTime, firstResponseTime, isRegion);
442 " instSeqNum = %d\n", address, instSeqNum);
451 "reqsAllIssued=%d\n", reqsAllIssued,
484 Cycles initialRequestTime,
485 Cycles forwardRequestTime,
490 initialRequestTime, forwardRequestTime, firstResponseTime,
498 Cycles initialRequestTime,
499 Cycles forwardRequestTime,
507 fatal_if(crequest->getRubyType() != RubyRequestType_LD,
508 "readCallback received non-read type response\n");
512 while (crequest->getRubyType() == RubyRequestType_LD) {
514 forwardRequestTime, firstResponseTime, isRegion);
538 Cycles initialRequestTime,
539 Cycles forwardRequestTime,
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)) {
580 "WARNING. Data not transfered from Ruby to M5 for type " \
582 RubyRequestType_to_string(
type));
601 RubyRequestType req_type = RubyRequestType_NULL;
604 assert(!pkt->
req->isLLSC());
605 assert(!pkt->
req->isLockedRMW());
606 assert(!pkt->
req->isInstFetch());
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;
616 req_type = RubyRequestType_ST;
618 panic(
"Unsupported ruby packet type\n");
630 assert(pkt->
req->hasInstSeqNum());
675 return RequestStatus_Issued;
678 template <
class KEY,
class VALUE>
680 operator<<(std::ostream &out,
const std::unordered_map<KEY, VALUE> &map)
683 for (
auto i = map.begin();
i != map.end(); ++
i)
684 out <<
" " <<
i->first <<
"=" <<
i->second;
702 safe_cast<RubyPort::SenderState*>(pkt->
senderState);
705 safe_cast<ComputeUnit::DataPort::SenderState*>
714 uint64_t seqNum = pkt->
req->getReqInstSeqNum();
722 auto citer = std::find_if(creqQueue.begin(), creqQueue.end(),
725 if (citer != creqQueue.end()) {
726 (*citer)->insertPacket(pkt);
770 " the pending write instruction list\n", seqNum,
774 safe_cast<RubyPort::SenderState*>(pkt->
senderState);
818 }
else if (pkt_list->empty()) {
825 InstSeqNum seq_num = pkt_list->front()->req->getReqInstSeqNum();
829 size_t pkt_list_size = pkt_list->size();
841 for (
auto creq : creqs) {
843 RubyRequestType_to_string(creq->getRubyType()),
850 assert(pkt_list_size >= pkt_list->size());
851 size_t pkt_list_diff = pkt_list_size - pkt_list->size();
854 num_remaining -= pkt_list_diff;
855 assert(num_remaining >= 0);
859 "Coalesced %d pkts for seqNum %d, %d remaining\n",
860 pkt_list_diff, seq_num, num_remaining);
870 for (
int i = 0;
i <
len;
i++) {
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");
924 for (
auto& pkt : mylist) {
926 safe_cast<RubyPort::SenderState *>(pkt->senderState);
928 assert(port != NULL);
930 pkt->senderState =
ss->predecessor;
957 Cycles initialRequestTime,
958 Cycles forwardRequestTime,
960 bool success,
bool isRegion)