Go to the documentation of this file.
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"
67 uint64_t seqNum = pkt->
req->getReqInstSeqNum();
87 auto instMapIter =
instMap.begin();
88 std::advance(instMapIter,
offset);
90 return &(instMapIter->second);
97 if (iter->second.empty()) {
113 ,inst.first, inst.second.size());
114 if (inst.first == instSeqNum) {
return false; }
123 ss <<
"Listing pending packets from " <<
instMap.size() <<
" instructions";
127 << inst.second.size() <<
" pending packets" << std::endl;
137 for (
auto &pkt : it.second) {
138 if (current_time - pkt->req->time() > threshold) {
139 std::stringstream
ss;
142 panic(
"Possible Deadlock detected. Aborting!\n"
143 "version: %d request.paddr: 0x%x uncoalescedTable: %d "
144 "current time: %u issue_time: %d difference: %d\n"
146 pkt->getAddr(),
instMap.size(), current_time,
147 pkt->req->time(), current_time - pkt->req->time(),
156 issueEvent([this]{
completeIssue(); },
"Issue coalesced request",
158 uncoalescedTable(
this),
159 deadlockCheckEvent([
this]{ wakeup(); },
"GPUCoalescer deadlock check"),
160 gmTokenPort(
name() +
".gmTokenPort",
this)
162 m_store_waiting_on_load_cycles = 0;
163 m_store_waiting_on_store_cycles = 0;
164 m_load_waiting_on_store_cycles = 0;
165 m_load_waiting_on_load_cycles = 0;
167 m_outstanding_count = 0;
169 coalescingWindow =
p->max_coalesces_per_cycle;
171 m_max_outstanding_requests = 0;
172 m_instCache_ptr =
nullptr;
173 m_dataCache_ptr =
nullptr;
175 m_instCache_ptr =
p->icache;
176 m_dataCache_ptr =
p->dcache;
177 m_max_outstanding_requests =
p->max_outstanding_requests;
178 m_deadlock_threshold =
p->deadlock_threshold;
180 assert(m_max_outstanding_requests > 0);
181 assert(m_deadlock_threshold > 0);
182 assert(m_instCache_ptr);
183 assert(m_dataCache_ptr);
185 m_runningGarnetStandalone =
p->garnet_standalone;
195 if (if_name ==
"gmTokenPort") {
208 for (
auto& req : requestList.second) {
210 std::stringstream
ss;
212 warn(
"GPUCoalescer %d Possible deadlock detected!\n%s\n",
214 panic(
"Aborting due to deadlock!\n");
233 <<
" outstanding requests in the coalesced table\n";
236 for (
auto& request : requestList.second) {
238 <<
"\tInstruction sequence number: "
239 << request->getSeqNum() <<
"\n"
241 << RubyRequestType_to_string(request->getRubyType()) <<
"\n"
242 <<
"\t\tNumber of associated packets: "
243 << request->getPackets().size() <<
"\n"
244 <<
"\t\tIssue time: "
246 <<
"\t\tDifference from current tick: "
260 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
263 for (
int j = 0;
j < MachineType_NUM;
j++) {
268 for (
int i = 0;
i < MachineType_NUM;
i++) {
316 Cycles initialRequestTime,
317 Cycles forwardRequestTime,
321 initialRequestTime, forwardRequestTime, firstResponseTime,
329 Cycles initialRequestTime,
330 Cycles forwardRequestTime,
340 forwardRequestTime, firstResponseTime, isRegion);
360 " instSeqNum = %d\n", address, instSeqNum);
369 "reqsAllIssued=%d\n", reqsAllIssued,
402 Cycles initialRequestTime,
403 Cycles forwardRequestTime,
408 initialRequestTime, forwardRequestTime, firstResponseTime,
416 Cycles initialRequestTime,
417 Cycles forwardRequestTime,
425 fatal_if(crequest->getRubyType() != RubyRequestType_LD,
426 "readCallback received non-read type response\n");
430 while (crequest->getRubyType() == RubyRequestType_LD) {
432 forwardRequestTime, firstResponseTime, isRegion);
456 Cycles initialRequestTime,
457 Cycles forwardRequestTime,
479 pktList.size(), request_line_address);
480 for (
auto& pkt : pktList) {
481 request_address = pkt->
getAddr();
482 if (pkt->
getPtr<uint8_t>()) {
483 if ((
type == RubyRequestType_LD) ||
484 (
type == RubyRequestType_ATOMIC) ||
485 (
type == RubyRequestType_ATOMIC_RETURN) ||
486 (
type == RubyRequestType_IFETCH) ||
487 (
type == RubyRequestType_RMW_Read) ||
488 (
type == RubyRequestType_Locked_RMW_Read) ||
489 (
type == RubyRequestType_Load_Linked)) {
498 "WARNING. Data not transfered from Ruby to M5 for type " \
500 RubyRequestType_to_string(
type));
519 RubyRequestType req_type = RubyRequestType_NULL;
522 assert(!pkt->
req->isLLSC());
523 assert(!pkt->
req->isLockedRMW());
524 assert(!pkt->
req->isInstFetch());
527 if (pkt->
req->isAtomicReturn()) {
528 req_type = RubyRequestType_ATOMIC_RETURN;
529 }
else if (pkt->
req->isAtomicNoReturn()) {
530 req_type = RubyRequestType_ATOMIC_NO_RETURN;
531 }
else if (pkt->
isRead()) {
532 req_type = RubyRequestType_LD;
534 req_type = RubyRequestType_ST;
536 panic(
"Unsupported ruby packet type\n");
548 assert(pkt->
req->hasInstSeqNum());
575 return RequestStatus_Issued;
578 template <
class KEY,
class VALUE>
580 operator<<(ostream &out,
const std::unordered_map<KEY, VALUE> &map)
583 for (
auto i = map.begin();
i != map.end(); ++
i)
584 out <<
" " <<
i->first <<
"=" <<
i->second;
602 uint64_t seqNum = pkt->
req->getReqInstSeqNum();
610 auto citer = std::find_if(creqQueue.begin(), creqQueue.end(),
613 if (citer != creqQueue.end()) {
614 (*citer)->insertPacket(pkt);
637 RubyRequestType_to_string(creq->
getRubyType()), seqNum);
657 " the pending write instruction list\n", seqNum,
661 safe_cast<RubyPort::SenderState*>(pkt->
senderState);
678 safe_cast<ComputeUnit::DataPort::SenderState*>
725 for (
int i = 0;
i <
len;
i++) {
757 fatal_if((crequest->getRubyType() != RubyRequestType_ATOMIC &&
758 crequest->getRubyType() != RubyRequestType_ATOMIC_RETURN &&
759 crequest->getRubyType() != RubyRequestType_ATOMIC_NO_RETURN),
760 "atomicCallback saw non-atomic type response\n");
779 for (
auto& pkt : mylist) {
781 safe_cast<RubyPort::SenderState *>(pkt->senderState);
783 assert(port != NULL);
785 pkt->senderState =
ss->predecessor;
812 Cycles initialRequestTime,
813 Cycles forwardRequestTime,
815 bool success,
bool isRegion)
831 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
839 for (
int i = 0;
i < MachineType_NUM;
i++) {
856 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
859 for (
int j = 0;
j < MachineType_NUM;
j++) {
virtual void regStats()
Callback to set stat parameters.
Cycles m_deadlock_threshold
bool scheduled() const
Determine if the current event is scheduled.
virtual void issueMemSyncRequest(PacketPtr pkt)
void ruby_hit_callback(PacketPtr pkt)
Stats::Histogram m_latencyHist
Histogram for holding latency profile of all requests.
RubyRequestType getRubyType() const
Addr makeLineAddress(Addr addr)
void insertPacket(PacketPtr pkt)
std::vector< std::vector< Stats::Histogram * > > m_missTypeMachLatencyHist
void writeCompleteCallback(Addr address, uint64_t instSeqNum, MachineType mach)
bool receiveWriteCompleteAck()
void evictionCallback(Addr address)
GMTokenPort & getGMTokenPort()
void printRequestTable(std::stringstream &ss)
RubyGPUCoalescerParams Params
uint64_t Tick
Tick count type.
void printProgress(std::ostream &out) const
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void insertPacket(PacketPtr pkt)
std::vector< int > newKernelEnds
RequestPtr req
A pointer to the original request.
void kernelCallback(int wavefront_id)
int getNumPendingStores()
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void addPendingReq(RubyPort::MemResponsePort *port, GPUDynInstPtr inst, bool usingRubyTester)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
PacketPtr getFirstPkt() const
void regStats() override
Callback to set stat parameters.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
EventFunctionWrapper deadlockCheckEvent
std::vector< Stats::Histogram * > m_InitialToForwardDelayHist
Stats::Histogram m_outstandReqHist
Histogram for number of outstanding requests per cycle.
void completeHitCallback(std::vector< PacketPtr > &mylist)
void schedule(Event &event, Tick when)
void printRequestTable(std::stringstream &ss)
Tick cyclesToTicks(Cycles c) const
std::map< Addr, std::deque< CoalescedRequest * > > coalescedTable
std::vector< Stats::Histogram * > m_IssueToInitialDelayHist
Histograms for recording the breakdown of miss latency.
virtual void atomicCallback(Addr address, MachineType mach, const DataBlock &data)
void print(std::ostream &out) const
Ports are used to interface objects to each other.
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
std::vector< Stats::Histogram * > m_typeLatencyHist
virtual RubyRequestType getRequestType(PacketPtr pkt)
UncoalescedTable(GPUCoalescer *gc)
std::unordered_map< uint64_t, PendingWriteInst > pendingWriteInsts
void insertKernel(int wavefront_id, PacketPtr pkt)
EventFunctionWrapper issueEvent
std::vector< Stats::Histogram * > m_ForwardToFirstResponseDelayHist
void resetStats() override
Callback to reset stats.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void ackWriteCompletion(bool usingRubyTester)
const std::string & name()
void writeCallback(Addr address, DataBlock &data)
RequestStatus makeRequest(PacketPtr pkt) override
void readCallback(Addr address, DataBlock &data)
bool coalescePacket(PacketPtr pkt)
GPUDynInstPtr _gpuDynInst
MemCmd cmd
The command field of the packet.
std::vector< Stats::Histogram * > m_missTypeLatencyHist
void recordMissLatency(CoalescedRequest *crequest, MachineType mach, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime, bool success, bool isRegion)
bool areRequestsDone(const uint64_t instSeqNum)
Overload hash function for BasicBlockRange type.
std::vector< Stats::Histogram * > m_FirstResponseToCompletionDelayHist
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
std::unordered_map< int, PacketPtr > kernelEndList
Addr getOffset(Addr addr)
std::vector< Stats::Histogram * > m_missMachLatencyHist
Histograms for profiling the latencies for requests that required external messages.
std::map< uint64_t, PerInstPackets > instMap
int m_max_outstanding_requests
void reset()
Reset stat value to default.
void hitCallback(PacketPtr pkt)
std::shared_ptr< GPUDynInst > GPUDynInstPtr
Cycles is a wrapper class for representing cycle counts, i.e.
T * getPtr()
get a pointer to the data ptr.
void checkDeadlock(Tick threshold)
std::vector< PacketPtr > & getPackets()
virtual void issueRequest(CoalescedRequest *crequest)=0
Histogram & init(size_type size)
Set the parameters of this histogram.
SenderState * senderState
This packet's sender state.
Stats::Histogram m_missLatencyHist
Histogram for holding latency profile of all requests that miss in the controller connected to this s...
static const Priority Progress_Event_Pri
Progress events come at the end.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
void setIssueTime(Cycles _issueTime)
std::string printAddress(Addr addr)
PerInstPackets * getInstPackets(int offset)
void ruby_eviction_callback(Addr address)
void sendTokens(int num_tokens)
Return num_tokens tokens back to the request port.
GPUCoalescer(const Params *)
void setRubyType(RubyRequestType type)
#define panic(...)
This implements a cprintf based panic() function.
Tick curTick()
The current simulated tick.
std::ostream & operator<<(ostream &out, const std::unordered_map< KEY, VALUE > &map)
UncoalescedTable uncoalescedTable
void hitCallback(CoalescedRequest *crequest, MachineType mach, DataBlock &data, bool success, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime, bool isRegion)
Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17