mem: Use the range cache for lookup as well as access
This patch changes the range cache used in the global physical memory to be an iterator so that we can use it not only as part of isMemAddr, but also access and functionalAccess. This matches use-cases where a core is using the atomic non-caching memory mode, and repeatedly calls isMemAddr and access. Linux boot on aarch32, with a single atomic CPU, is now more than 30% faster when using "--fastmem" compared to not using the direct memory access.
This commit is contained in:
parent
d0e1b8a19c
commit
57758ca685
2 changed files with 27 additions and 16 deletions
|
@ -60,7 +60,7 @@ using namespace std;
|
||||||
|
|
||||||
PhysicalMemory::PhysicalMemory(const string& _name,
|
PhysicalMemory::PhysicalMemory(const string& _name,
|
||||||
const vector<AbstractMemory*>& _memories) :
|
const vector<AbstractMemory*>& _memories) :
|
||||||
_name(_name), size(0)
|
_name(_name), rangeCache(addrMap.end()), size(0)
|
||||||
{
|
{
|
||||||
// add the memories from the system to the address map as
|
// add the memories from the system to the address map as
|
||||||
// appropriate
|
// appropriate
|
||||||
|
@ -181,7 +181,9 @@ bool
|
||||||
PhysicalMemory::isMemAddr(Addr addr) const
|
PhysicalMemory::isMemAddr(Addr addr) const
|
||||||
{
|
{
|
||||||
// see if the address is within the last matched range
|
// see if the address is within the last matched range
|
||||||
if (!rangeCache.contains(addr)) {
|
if (rangeCache != addrMap.end() && rangeCache->first.contains(addr)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
// lookup in the interval tree
|
// lookup in the interval tree
|
||||||
const auto& r = addrMap.find(addr);
|
const auto& r = addrMap.find(addr);
|
||||||
if (r == addrMap.end()) {
|
if (r == addrMap.end()) {
|
||||||
|
@ -189,13 +191,9 @@ PhysicalMemory::isMemAddr(Addr addr) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// the range is in the tree, update the cache
|
// the range is in the tree, update the cache
|
||||||
rangeCache = r->first;
|
rangeCache = r;
|
||||||
}
|
|
||||||
|
|
||||||
assert(addrMap.find(addr) != addrMap.end());
|
|
||||||
|
|
||||||
// either matched the cache or found in the tree
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddrRangeList
|
AddrRangeList
|
||||||
|
@ -239,9 +237,15 @@ PhysicalMemory::access(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
assert(pkt->isRequest());
|
assert(pkt->isRequest());
|
||||||
Addr addr = pkt->getAddr();
|
Addr addr = pkt->getAddr();
|
||||||
|
if (rangeCache != addrMap.end() && rangeCache->first.contains(addr)) {
|
||||||
|
rangeCache->second->access(pkt);
|
||||||
|
} else {
|
||||||
|
// do not update the cache here, as we typically call
|
||||||
|
// isMemAddr before calling access
|
||||||
const auto& m = addrMap.find(addr);
|
const auto& m = addrMap.find(addr);
|
||||||
assert(m != addrMap.end());
|
assert(m != addrMap.end());
|
||||||
m->second->access(pkt);
|
m->second->access(pkt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -249,9 +253,15 @@ PhysicalMemory::functionalAccess(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
assert(pkt->isRequest());
|
assert(pkt->isRequest());
|
||||||
Addr addr = pkt->getAddr();
|
Addr addr = pkt->getAddr();
|
||||||
|
if (rangeCache != addrMap.end() && rangeCache->first.contains(addr)) {
|
||||||
|
rangeCache->second->functionalAccess(pkt);
|
||||||
|
} else {
|
||||||
|
// do not update the cache here, as we typically call
|
||||||
|
// isMemAddr before calling functionalAccess
|
||||||
const auto& m = addrMap.find(addr);
|
const auto& m = addrMap.find(addr);
|
||||||
assert(m != addrMap.end());
|
assert(m != addrMap.end());
|
||||||
m->second->functionalAccess(pkt);
|
m->second->functionalAccess(pkt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -75,8 +75,9 @@ class PhysicalMemory : public Serializable
|
||||||
// Global address map
|
// Global address map
|
||||||
AddrRangeMap<AbstractMemory*> addrMap;
|
AddrRangeMap<AbstractMemory*> addrMap;
|
||||||
|
|
||||||
// a mutable cache for the last range that matched an address
|
// a mutable cache for the last address map iterator that matched
|
||||||
mutable AddrRange rangeCache;
|
// an address
|
||||||
|
mutable AddrRangeMap<AbstractMemory*>::const_iterator rangeCache;
|
||||||
|
|
||||||
// All address-mapped memories
|
// All address-mapped memories
|
||||||
std::vector<AbstractMemory*> memories;
|
std::vector<AbstractMemory*> memories;
|
||||||
|
|
Loading…
Reference in a new issue