ruby: make a RequestDesc class instead of std::pair
the RequestDesc was previously implemented as a std::pair, which made the implementation overly complex and error prone. here we encapsulate the packet, primary, and secondary types all in a single data structure with all members properly intialized in a ctor
This commit is contained in:
parent
90b087171b
commit
c7d4afd878
2 changed files with 31 additions and 19 deletions
|
@ -625,9 +625,8 @@ GPUCoalescer::hitCallback(GPUCoalescerRequest* srequest,
|
||||||
int len = reqCoalescer[request_line_address].size();
|
int len = reqCoalescer[request_line_address].size();
|
||||||
std::vector<PacketPtr> mylist;
|
std::vector<PacketPtr> mylist;
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
PacketPtr pkt = reqCoalescer[request_line_address][i].first;
|
PacketPtr pkt = reqCoalescer[request_line_address][i].pkt;
|
||||||
assert(type ==
|
assert(type == reqCoalescer[request_line_address][i].primaryType);
|
||||||
reqCoalescer[request_line_address][i].second[PrimaryType]);
|
|
||||||
request_address = pkt->getAddr();
|
request_address = pkt->getAddr();
|
||||||
request_line_address = makeLineAddress(pkt->getAddr());
|
request_line_address = makeLineAddress(pkt->getAddr());
|
||||||
if (pkt->getPtr<uint8_t>()) {
|
if (pkt->getPtr<uint8_t>()) {
|
||||||
|
@ -848,25 +847,22 @@ GPUCoalescer::makeRequest(PacketPtr pkt)
|
||||||
// let us see if we can coalesce this request with the previous
|
// let us see if we can coalesce this request with the previous
|
||||||
// requests from this cycle
|
// requests from this cycle
|
||||||
} else if (primary_type !=
|
} else if (primary_type !=
|
||||||
reqCoalescer[line_addr][0].second[PrimaryType]) {
|
reqCoalescer[line_addr][0].primaryType) {
|
||||||
// can't coalesce loads, stores and atomics!
|
// can't coalesce loads, stores and atomics!
|
||||||
return RequestStatus_Aliased;
|
return RequestStatus_Aliased;
|
||||||
} else if (pkt->req->isLockedRMW() ||
|
} else if (pkt->req->isLockedRMW() ||
|
||||||
reqCoalescer[line_addr][0].first->req->isLockedRMW()) {
|
reqCoalescer[line_addr][0].pkt->req->isLockedRMW()) {
|
||||||
// can't coalesce locked accesses, but can coalesce atomics!
|
// can't coalesce locked accesses, but can coalesce atomics!
|
||||||
return RequestStatus_Aliased;
|
return RequestStatus_Aliased;
|
||||||
} else if (pkt->req->hasContextId() && pkt->req->isRelease() &&
|
} else if (pkt->req->hasContextId() && pkt->req->isRelease() &&
|
||||||
pkt->req->contextId() !=
|
pkt->req->contextId() !=
|
||||||
reqCoalescer[line_addr][0].first->req->contextId()) {
|
reqCoalescer[line_addr][0].pkt->req->contextId()) {
|
||||||
// can't coalesce releases from different wavefronts
|
// can't coalesce releases from different wavefronts
|
||||||
return RequestStatus_Aliased;
|
return RequestStatus_Aliased;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in addition to the packet, we need to save both request types
|
// in addition to the packet, we need to save both request types
|
||||||
reqCoalescer[line_addr].push_back(
|
reqCoalescer[line_addr].emplace_back(pkt, primary_type, secondary_type);
|
||||||
RequestDesc(pkt, std::vector<RubyRequestType>()) );
|
|
||||||
reqCoalescer[line_addr].back().second.push_back(primary_type);
|
|
||||||
reqCoalescer[line_addr].back().second.push_back(secondary_type);
|
|
||||||
if (!issueEvent.scheduled())
|
if (!issueEvent.scheduled())
|
||||||
schedule(issueEvent, curTick());
|
schedule(issueEvent, curTick());
|
||||||
// TODO: issue hardware prefetches here
|
// TODO: issue hardware prefetches here
|
||||||
|
@ -910,7 +906,7 @@ GPUCoalescer::issueRequest(PacketPtr pkt, RubyRequestType secondary_type)
|
||||||
std::vector< std::pair<int,AtomicOpFunctor*> > atomicOps;
|
std::vector< std::pair<int,AtomicOpFunctor*> > atomicOps;
|
||||||
uint32_t tableSize = reqCoalescer[line_addr].size();
|
uint32_t tableSize = reqCoalescer[line_addr].size();
|
||||||
for (int i = 0; i < tableSize; i++) {
|
for (int i = 0; i < tableSize; i++) {
|
||||||
PacketPtr tmpPkt = reqCoalescer[line_addr][i].first;
|
PacketPtr tmpPkt = reqCoalescer[line_addr][i].pkt;
|
||||||
uint32_t tmpOffset = (tmpPkt->getAddr()) - line_addr;
|
uint32_t tmpOffset = (tmpPkt->getAddr()) - line_addr;
|
||||||
uint32_t tmpSize = tmpPkt->getSize();
|
uint32_t tmpSize = tmpPkt->getSize();
|
||||||
if (tmpPkt->isAtomicOp()) {
|
if (tmpPkt->isAtomicOp()) {
|
||||||
|
@ -1020,12 +1016,12 @@ GPUCoalescer::completeIssue()
|
||||||
// can be coalesced with the first request. So, only
|
// can be coalesced with the first request. So, only
|
||||||
// one request is issued per cacheline.
|
// one request is issued per cacheline.
|
||||||
RequestDesc info = reqCoalescer[newRequests[i]][0];
|
RequestDesc info = reqCoalescer[newRequests[i]][0];
|
||||||
PacketPtr pkt = info.first;
|
PacketPtr pkt = info.pkt;
|
||||||
DPRINTF(GPUCoalescer, "Completing for newReq %d: paddr %#x\n",
|
DPRINTF(GPUCoalescer, "Completing for newReq %d: paddr %#x\n",
|
||||||
i, pkt->req->getPaddr());
|
i, pkt->req->getPaddr());
|
||||||
// Insert this request to the read/writeRequestTables. These tables
|
// Insert this request to the read/writeRequestTables. These tables
|
||||||
// are used to track aliased requests in makeRequest subroutine
|
// are used to track aliased requests in makeRequest subroutine
|
||||||
bool found = insertRequest(pkt, info.second[PrimaryType]);
|
bool found = insertRequest(pkt, info.primaryType);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
panic("GPUCoalescer::makeRequest should never be called if the "
|
panic("GPUCoalescer::makeRequest should never be called if the "
|
||||||
|
@ -1033,7 +1029,7 @@ GPUCoalescer::completeIssue()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue request to ruby subsystem
|
// Issue request to ruby subsystem
|
||||||
issueRequest(pkt, info.second[SecondaryType]);
|
issueRequest(pkt, info.secondaryType);
|
||||||
}
|
}
|
||||||
newRequests.clear();
|
newRequests.clear();
|
||||||
|
|
||||||
|
@ -1107,9 +1103,9 @@ GPUCoalescer::atomicCallback(Addr address,
|
||||||
int len = reqCoalescer[request_line_address].size();
|
int len = reqCoalescer[request_line_address].size();
|
||||||
std::vector<PacketPtr> mylist;
|
std::vector<PacketPtr> mylist;
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
PacketPtr pkt = reqCoalescer[request_line_address][i].first;
|
PacketPtr pkt = reqCoalescer[request_line_address][i].pkt;
|
||||||
assert(srequest->m_type ==
|
assert(srequest->m_type ==
|
||||||
reqCoalescer[request_line_address][i].second[PrimaryType]);
|
reqCoalescer[request_line_address][i].primaryType);
|
||||||
request_address = (pkt->getAddr());
|
request_address = (pkt->getAddr());
|
||||||
request_line_address = makeLineAddress(request_address);
|
request_line_address = makeLineAddress(request_address);
|
||||||
if (pkt->getPtr<uint8_t>() &&
|
if (pkt->getPtr<uint8_t>() &&
|
||||||
|
|
|
@ -73,6 +73,24 @@ struct GPUCoalescerRequest
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RequestDesc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RequestDesc(PacketPtr pkt, RubyRequestType p_type, RubyRequestType s_type)
|
||||||
|
: pkt(pkt), primaryType(p_type), secondaryType(s_type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestDesc() : pkt(nullptr), primaryType(RubyRequestType_NULL),
|
||||||
|
secondaryType(RubyRequestType_NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketPtr pkt;
|
||||||
|
RubyRequestType primaryType;
|
||||||
|
RubyRequestType secondaryType;
|
||||||
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const GPUCoalescerRequest& obj);
|
std::ostream& operator<<(std::ostream& out, const GPUCoalescerRequest& obj);
|
||||||
|
|
||||||
class GPUCoalescer : public RubyPort
|
class GPUCoalescer : public RubyPort
|
||||||
|
@ -271,9 +289,7 @@ class GPUCoalescer : public RubyPort
|
||||||
// The secondary request type comprises a subset of RubyRequestTypes that
|
// The secondary request type comprises a subset of RubyRequestTypes that
|
||||||
// are understood by the L1 Controller. A primary request type can be any
|
// are understood by the L1 Controller. A primary request type can be any
|
||||||
// RubyRequestType.
|
// RubyRequestType.
|
||||||
enum {PrimaryType, SecondaryType};
|
typedef std::unordered_map<Addr, std::vector<RequestDesc>> CoalescingTable;
|
||||||
typedef std::pair<PacketPtr, std::vector<RubyRequestType> > RequestDesc;
|
|
||||||
typedef std::unordered_map<Addr, std::vector<RequestDesc> > CoalescingTable;
|
|
||||||
CoalescingTable reqCoalescer;
|
CoalescingTable reqCoalescer;
|
||||||
std::vector<Addr> newRequests;
|
std::vector<Addr> newRequests;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue