systemc: Reduce unnecessary backdoor request in atomic transaction (#795)
The backdoor request in b_transport is only used for hinting the dmi capability. Since most of traffic patterns are continous, we can cache the previous backdoor request result to spare the backdoor inspect of next request. Change-Id: I53c47226f949dd0be19d52cad0650fcfd62eebbc
This commit is contained in:
@@ -299,6 +299,24 @@ TlmToGem5Bridge<BITWIDTH>::destroyPacket(PacketPtr pkt)
|
||||
delete pkt;
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
void
|
||||
TlmToGem5Bridge<BITWIDTH>::cacheBackdoor(gem5::MemBackdoorPtr backdoor)
|
||||
{
|
||||
if (backdoor == nullptr) return;
|
||||
|
||||
// We only need to register the callback at the first time.
|
||||
if (requestedBackdoors.find(backdoor) == requestedBackdoors.end()) {
|
||||
backdoor->addInvalidationCallback(
|
||||
[this](const MemBackdoor &backdoor)
|
||||
{
|
||||
invalidateDmi(backdoor);
|
||||
}
|
||||
);
|
||||
requestedBackdoors.emplace(backdoor);
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned int BITWIDTH>
|
||||
void
|
||||
TlmToGem5Bridge<BITWIDTH>::invalidateDmi(const gem5::MemBackdoor &backdoor)
|
||||
@@ -360,9 +378,29 @@ TlmToGem5Bridge<BITWIDTH>::b_transport(tlm::tlm_generic_payload &trans,
|
||||
pkt->pushSenderState(new Gem5SystemC::TlmSenderState(trans));
|
||||
|
||||
MemBackdoorPtr backdoor = nullptr;
|
||||
Tick ticks = bmp.sendAtomicBackdoor(pkt, backdoor);
|
||||
if (backdoor)
|
||||
Tick ticks = 0;
|
||||
|
||||
// Check if we have a backdoor meet the request. If yes, we can just hints
|
||||
// the requestor the DMI is supported.
|
||||
for (auto& b : requestedBackdoors) {
|
||||
if (pkt->getAddrRange().isSubset(b->range()) &&
|
||||
((!pkt->isWrite() && b->readable()) ||
|
||||
(pkt->isWrite() && b->writeable()))) {
|
||||
backdoor = b;
|
||||
}
|
||||
}
|
||||
|
||||
if (backdoor) {
|
||||
ticks = bmp.sendAtomic(pkt);
|
||||
} else {
|
||||
ticks = bmp.sendAtomicBackdoor(pkt, backdoor);
|
||||
}
|
||||
|
||||
// Hints the requestor the DMI is supported.
|
||||
if (backdoor) {
|
||||
trans.set_dmi_allowed(true);
|
||||
cacheBackdoor(backdoor);
|
||||
}
|
||||
|
||||
// send an atomic request to gem5
|
||||
panic_if(pkt->needsResponse() && !pkt->isResponse(),
|
||||
@@ -450,17 +488,7 @@ TlmToGem5Bridge<BITWIDTH>::get_direct_mem_ptr(tlm::tlm_generic_payload &trans,
|
||||
if (backdoor->writeable())
|
||||
access = (access_t)(access | tlm::tlm_dmi::DMI_ACCESS_WRITE);
|
||||
dmi_data.set_granted_access(access);
|
||||
|
||||
// We only need to register the callback at the first time.
|
||||
if (requestedBackdoors.find(backdoor) == requestedBackdoors.end()) {
|
||||
backdoor->addInvalidationCallback(
|
||||
[this](const MemBackdoor &backdoor)
|
||||
{
|
||||
invalidateDmi(backdoor);
|
||||
}
|
||||
);
|
||||
requestedBackdoors.emplace(backdoor);
|
||||
}
|
||||
cacheBackdoor(backdoor);
|
||||
}
|
||||
|
||||
trans.set_response_status(tlm::TLM_OK_RESPONSE);
|
||||
|
||||
@@ -143,6 +143,8 @@ class TlmToGem5Bridge : public TlmToGem5BridgeBase
|
||||
|
||||
void invalidateDmi(const gem5::MemBackdoor &backdoor);
|
||||
|
||||
void cacheBackdoor(gem5::MemBackdoorPtr backdoor);
|
||||
|
||||
protected:
|
||||
// payload event call back
|
||||
void peq_cb(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase);
|
||||
|
||||
Reference in New Issue
Block a user