38 #include "config/the_isa.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"
55 #include "params/RubyGPUCoalescer.hh"
65 uint64_t seqNum = pkt->
req->getReqInstSeqNum();
105 auto instMapIter =
instMap.begin();
106 std::advance(instMapIter,
offset);
108 return &(instMapIter->second);
121 assert(iter->second.empty());
142 ,inst.first, inst.second.size());
143 if (inst.first == instSeqNum) {
return false; }
152 ss <<
"Listing pending packets from " <<
instMap.size() <<
" instructions";
156 << inst.second.size() <<
" pending packets" << std::endl;
166 for (
auto &pkt : it.second) {
167 if (current_time - pkt->req->time() > threshold) {
168 std::stringstream
ss;
171 panic(
"Possible Deadlock detected. Aborting!\n"
172 "version: %d request.paddr: 0x%x uncoalescedTable: %d "
173 "current time: %u issue_time: %d difference: %d\n"
175 pkt->getAddr(),
instMap.size(), current_time,
176 pkt->req->time(), current_time - pkt->req->time(),
185 issueEvent([this]{
completeIssue(); },
"Issue coalesced request",
187 uncoalescedTable(
this),
188 deadlockCheckEvent([
this]{ wakeup(); },
"GPUCoalescer deadlock check"),
189 gmTokenPort(
name() +
".gmTokenPort",
this)
191 m_store_waiting_on_load_cycles = 0;
192 m_store_waiting_on_store_cycles = 0;
193 m_load_waiting_on_store_cycles = 0;
194 m_load_waiting_on_load_cycles = 0;
196 m_outstanding_count = 0;
198 coalescingWindow =
p.max_coalesces_per_cycle;
200 m_max_outstanding_requests = 0;
201 m_instCache_ptr =
nullptr;
202 m_dataCache_ptr =
nullptr;
204 m_instCache_ptr =
p.icache;
205 m_dataCache_ptr =
p.dcache;
206 m_max_outstanding_requests =
p.max_outstanding_requests;
207 m_deadlock_threshold =
p.deadlock_threshold;
209 assert(m_max_outstanding_requests > 0);
210 assert(m_deadlock_threshold > 0);
211 assert(m_instCache_ptr);
212 assert(m_dataCache_ptr);
214 m_runningGarnetStandalone =
p.garnet_standalone;
220 m_outstandReqHist.init(10);
221 m_latencyHist.init(10);
222 m_missLatencyHist.init(10);
224 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
226 m_typeLatencyHist[
i]->init(10);
229 m_missTypeLatencyHist[
i]->init(10);
232 for (
int i = 0;
i < MachineType_NUM;
i++) {
234 m_missMachLatencyHist[
i]->init(10);
237 m_IssueToInitialDelayHist[
i]->init(10);
240 m_InitialToForwardDelayHist[
i]->init(10);
243 m_ForwardToFirstResponseDelayHist[
i]->init(10);
246 m_FirstResponseToCompletionDelayHist[
i]->init(10);
249 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
252 for (
int j = 0;
j < MachineType_NUM;
j++) {
254 m_missTypeMachLatencyHist[
i][
j]->init(10);
267 if (if_name ==
"gmTokenPort") {
280 for (
auto& req : requestList.second) {
282 std::stringstream
ss;
284 warn(
"GPUCoalescer %d Possible deadlock detected!\n%s\n",
286 panic(
"Aborting due to deadlock!\n");
305 <<
" outstanding requests in the coalesced table\n";
308 for (
auto& request : requestList.second) {
310 <<
"\tInstruction sequence number: "
311 << request->getSeqNum() <<
"\n"
313 << RubyRequestType_to_string(request->getRubyType()) <<
"\n"
314 <<
"\t\tNumber of associated packets: "
315 << request->getPackets().size() <<
"\n"
316 <<
"\t\tIssue time: "
318 <<
"\t\tDifference from current tick: "
332 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
335 for (
int j = 0;
j < MachineType_NUM;
j++) {
340 for (
int i = 0;
i < MachineType_NUM;
i++) {
388 Cycles initialRequestTime,
389 Cycles forwardRequestTime,
393 initialRequestTime, forwardRequestTime, firstResponseTime,
401 Cycles initialRequestTime,
402 Cycles forwardRequestTime,
412 forwardRequestTime, firstResponseTime, isRegion);
432 " instSeqNum = %d\n", address, instSeqNum);
441 "reqsAllIssued=%d\n", reqsAllIssued,
474 Cycles initialRequestTime,
475 Cycles forwardRequestTime,
480 initialRequestTime, forwardRequestTime, firstResponseTime,
488 Cycles initialRequestTime,
489 Cycles forwardRequestTime,
497 fatal_if(crequest->getRubyType() != RubyRequestType_LD,
498 "readCallback received non-read type response\n");
502 while (crequest->getRubyType() == RubyRequestType_LD) {
504 forwardRequestTime, firstResponseTime, isRegion);
528 Cycles initialRequestTime,
529 Cycles forwardRequestTime,
551 pktList.size(), request_line_address);
552 for (
auto& pkt : pktList) {
553 request_address = pkt->
getAddr();
554 if (pkt->
getPtr<uint8_t>()) {
555 if ((
type == RubyRequestType_LD) ||
556 (
type == RubyRequestType_ATOMIC) ||
557 (
type == RubyRequestType_ATOMIC_RETURN) ||
558 (
type == RubyRequestType_IFETCH) ||
559 (
type == RubyRequestType_RMW_Read) ||
560 (
type == RubyRequestType_Locked_RMW_Read) ||
561 (
type == RubyRequestType_Load_Linked)) {
570 "WARNING. Data not transfered from Ruby to M5 for type " \
572 RubyRequestType_to_string(
type));
591 RubyRequestType req_type = RubyRequestType_NULL;
594 assert(!pkt->
req->isLLSC());
595 assert(!pkt->
req->isLockedRMW());
596 assert(!pkt->
req->isInstFetch());
599 if (pkt->
req->isAtomicReturn()) {
600 req_type = RubyRequestType_ATOMIC_RETURN;
601 }
else if (pkt->
req->isAtomicNoReturn()) {
602 req_type = RubyRequestType_ATOMIC_NO_RETURN;
603 }
else if (pkt->
isRead()) {
604 req_type = RubyRequestType_LD;
606 req_type = RubyRequestType_ST;
608 panic(
"Unsupported ruby packet type\n");
620 assert(pkt->
req->hasInstSeqNum());
638 num_packets =
getDynInst(pkt)->exec_mask.count();
662 return RequestStatus_Issued;
665 template <
class KEY,
class VALUE>
667 operator<<(std::ostream &out,
const std::unordered_map<KEY, VALUE> &map)
670 for (
auto i = map.begin();
i != map.end(); ++
i)
671 out <<
" " <<
i->first <<
"=" <<
i->second;
689 safe_cast<RubyPort::SenderState*>(pkt->
senderState);
692 safe_cast<ComputeUnit::DataPort::SenderState*>
701 uint64_t seqNum = pkt->
req->getReqInstSeqNum();
709 auto citer = std::find_if(creqQueue.begin(), creqQueue.end(),
712 if (citer != creqQueue.end()) {
713 (*citer)->insertPacket(pkt);
757 " the pending write instruction list\n", seqNum,
761 safe_cast<RubyPort::SenderState*>(pkt->
senderState);
805 }
else if (pkt_list->empty()) {
812 InstSeqNum seq_num = pkt_list->front()->req->getReqInstSeqNum();
816 size_t pkt_list_size = pkt_list->size();
828 for (
auto creq : creqs) {
830 RubyRequestType_to_string(creq->getRubyType()),
837 assert(pkt_list_size >= pkt_list->size());
838 size_t pkt_list_diff = pkt_list_size - pkt_list->size();
841 num_remaining -= pkt_list_diff;
842 assert(num_remaining >= 0);
846 "Coalesced %d pkts for seqNum %d, %d remaining\n",
847 pkt_list_diff, seq_num, num_remaining);
857 for (
int i = 0;
i <
len;
i++) {
889 fatal_if((crequest->getRubyType() != RubyRequestType_ATOMIC &&
890 crequest->getRubyType() != RubyRequestType_ATOMIC_RETURN &&
891 crequest->getRubyType() != RubyRequestType_ATOMIC_NO_RETURN),
892 "atomicCallback saw non-atomic type response\n");
911 for (
auto& pkt : mylist) {
913 safe_cast<RubyPort::SenderState *>(pkt->senderState);
915 assert(port != NULL);
917 pkt->senderState =
ss->predecessor;
944 Cycles initialRequestTime,
945 Cycles forwardRequestTime,
947 bool success,
bool isRegion)