mem: Use the range cache for lookup as well as access
authorAndreas Hansson <andreas.hansson@arm.com>
Mon, 16 Feb 2015 08:33:37 +0000 (03:33 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Mon, 16 Feb 2015 08:33:37 +0000 (03:33 -0500)
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.

src/mem/physical.cc
src/mem/physical.hh

index 8eacfccb1c4b1519b2a78c5927e7b9c6e88fcce8..b5627cfa2ec46546ed22df66c86cb6e25c595854 100644 (file)
@@ -60,7 +60,7 @@ using namespace std;
 
 PhysicalMemory::PhysicalMemory(const string& _name,
                                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
     // appropriate
@@ -181,7 +181,9 @@ bool
 PhysicalMemory::isMemAddr(Addr addr) const
 {
     // 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
         const auto& r = addrMap.find(addr);
         if (r == addrMap.end()) {
@@ -189,13 +191,9 @@ PhysicalMemory::isMemAddr(Addr addr) const
             return false;
         }
         // the range is in the tree, update the cache
-        rangeCache = r->first;
+        rangeCache = r;
+        return true;
     }
-
-    assert(addrMap.find(addr) != addrMap.end());
-
-    // either matched the cache or found in the tree
-    return true;
 }
 
 AddrRangeList
@@ -239,9 +237,15 @@ PhysicalMemory::access(PacketPtr pkt)
 {
     assert(pkt->isRequest());
     Addr addr = pkt->getAddr();
-    const auto& m = addrMap.find(addr);
-    assert(m != addrMap.end());
-    m->second->access(pkt);
+    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);
+        assert(m != addrMap.end());
+        m->second->access(pkt);
+    }
 }
 
 void
@@ -249,9 +253,15 @@ PhysicalMemory::functionalAccess(PacketPtr pkt)
 {
     assert(pkt->isRequest());
     Addr addr = pkt->getAddr();
-    const auto& m = addrMap.find(addr);
-    assert(m != addrMap.end());
-    m->second->functionalAccess(pkt);
+    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);
+        assert(m != addrMap.end());
+        m->second->functionalAccess(pkt);
+    }
 }
 
 void
index 51ec1cbd362c32380bc7beaa8602b3e944244c40..b8d26fd4b05db00fc357877c1b954475ea4e2dec 100644 (file)
@@ -75,8 +75,9 @@ class PhysicalMemory : public Serializable
     // Global address map
     AddrRangeMap<AbstractMemory*> addrMap;
 
-    // a mutable cache for the last range that matched an address
-    mutable AddrRange rangeCache;
+    // a mutable cache for the last address map iterator that matched
+    // an address
+    mutable AddrRangeMap<AbstractMemory*>::const_iterator rangeCache;
 
     // All address-mapped memories
     std::vector<AbstractMemory*> memories;