mem: Add deferred packet class to prefetcher
authorAndreas Hansson <andreas.hansson@arm.com>
Tue, 19 Feb 2013 10:56:06 +0000 (05:56 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Tue, 19 Feb 2013 10:56:06 +0000 (05:56 -0500)
This patch removes the time field from the packet as it was only used
by the preftecher. Similar to the packet queue, the prefetcher now
wraps the packet in a deferred packet, which also has a tick
representing the absolute time when the packet should be sent.

src/mem/cache/prefetch/base.cc
src/mem/cache/prefetch/base.hh
src/mem/packet.hh

index ddf1c1b31348b8106455c05fb0c20e84419aea59..6463f78f84e60bc90956f2e4ccd99eed373ccb1c 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2013 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2005 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -139,9 +151,9 @@ BasePrefetcher::getPacket()
         return NULL;
     }
 
-    PacketPtr pkt = *pf.begin();
+    PacketPtr pkt = pf.begin()->pkt;
     while (!pf.empty()) {
-        pkt = *pf.begin();
+        pkt = pf.begin()->pkt;
         pf.pop_front();
 
         Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1);
@@ -168,20 +180,20 @@ BasePrefetcher::getPacket()
 
 
 Tick
-BasePrefetcher::notify(PacketPtr &pkt, Tick time)
+BasePrefetcher::notify(PacketPtr &pkt, Tick tick)
 {
     if (!pkt->req->isUncacheable() && !(pkt->req->isInstFetch() && onlyData)) {
         // Calculate the blk address
         Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1);
 
         // Check if miss is in pfq, if so remove it
-        std::list<PacketPtr>::iterator iter = inPrefetch(blk_addr);
+        std::list<DeferredPacket>::iterator iter = inPrefetch(blk_addr);
         if (iter != pf.end()) {
             DPRINTF(HWPrefetch, "Saw a miss to a queued prefetch addr: "
                     "0x%x, removing it\n", blk_addr);
             pfRemovedMSHR++;
-            delete (*iter)->req;
-            delete (*iter);
+            delete iter->pkt->req;
+            delete iter->pkt;
             iter = pf.erase(iter);
             if (pf.empty())
                 cache->deassertMemSideBusRequest(BaseCache::Request_PF);
@@ -196,12 +208,12 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time)
             iter = pf.end();
             if (iter != pf.begin())
                 iter--;
-            while (!pf.empty() && ((*iter)->time >= time)) {
+            while (!pf.empty() && iter->tick >= tick) {
                 pfSquashed++;
                 DPRINTF(HWPrefetch, "Squashing old prefetch addr: 0x%x\n",
-                        (*iter)->getAddr());
-                delete (*iter)->req;
-                delete (*iter);
+                        iter->pkt->getAddr());
+                delete iter->pkt->req;
+                delete iter->pkt;
                 iter = pf.erase(iter);
                 if (iter != pf.begin())
                     iter--;
@@ -241,12 +253,10 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time)
             prefetch->req->setThreadContext(pkt->req->contextId(),
                                             pkt->req->threadId());
 
-            prefetch->time = time + clockPeriod() * *delayIter;
-
             // We just remove the head if we are full
             if (pf.size() == size) {
                 pfRemovedFull++;
-                PacketPtr old_pkt = *pf.begin();
+                PacketPtr old_pkt = pf.begin()->pkt;
                 DPRINTF(HWPrefetch, "Prefetch queue full, "
                         "removing oldest 0x%x\n", old_pkt->getAddr());
                 delete old_pkt->req;
@@ -254,20 +264,21 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time)
                 pf.pop_front();
             }
 
-            pf.push_back(prefetch);
+            pf.push_back(DeferredPacket(tick + clockPeriod() * *delayIter,
+                                        prefetch));
         }
     }
 
-    return pf.empty() ? 0 : pf.front()->time;
+    return pf.empty() ? 0 : pf.front().tick;
 }
 
-std::list<PacketPtr>::iterator
+std::list<BasePrefetcher::DeferredPacket>::iterator
 BasePrefetcher::inPrefetch(Addr address)
 {
     // Guaranteed to only be one match, we always check before inserting
-    std::list<PacketPtr>::iterator iter;
+    std::list<DeferredPacket>::iterator iter;
     for (iter = pf.begin(); iter != pf.end(); iter++) {
-        if (((*iter)->getAddr() & ~(Addr)(blkSize-1)) == address) {
+        if ((iter->pkt->getAddr() & ~(Addr)(blkSize-1)) == address) {
             return iter;
         }
     }
index 99385c1c1929d3f1e64b7796c859cdc0ac077a8e..07ca3dd6ff074d77f00981271933ce93b2763a6b 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2013 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2005 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -49,8 +61,18 @@ class BasePrefetcher : public ClockedObject
 {
   protected:
 
+    /** A deferred packet, buffered to transmit later. */
+    class DeferredPacket {
+      public:
+        Tick tick;      ///< The tick when the packet is ready to transmit
+        PacketPtr pkt;  ///< Pointer to the packet to transmit
+        DeferredPacket(Tick t, PacketPtr p)
+            : tick(t), pkt(p)
+        {}
+    };
+
     /** The Prefetch Queue. */
-    std::list<PacketPtr> pf;
+    std::list<DeferredPacket> pf;
 
     // PARAMETERS
 
@@ -113,7 +135,7 @@ class BasePrefetcher : public ClockedObject
      * misses, depending on cache parameters.)
      * @retval Time of next prefetch availability, or 0 if none.
      */
-    Tick notify(PacketPtr &pkt, Tick time);
+    Tick notify(PacketPtr &pkt, Tick tick);
 
     bool inCache(Addr addr);
 
@@ -128,14 +150,14 @@ class BasePrefetcher : public ClockedObject
 
     Tick nextPrefetchReadyTime()
     {
-        return pf.empty() ? MaxTick : pf.front()->time;
+        return pf.empty() ? MaxTick : pf.front().tick;
     }
 
     virtual void calculatePrefetch(PacketPtr &pkt,
                                    std::list<Addr> &addresses,
                                    std::list<Cycles> &delays) = 0;
 
-    std::list<PacketPtr>::iterator inPrefetch(Addr address);
+    std::list<DeferredPacket>::iterator inPrefetch(Addr address);
 
     /**
      * Utility function: are addresses a and b on the same VM page?
index 6d9e88b8f0dd191ca00670ea47230ca9de862495..181320850cc73a1356a96d68961b6eb46d0d9d31 100644 (file)
@@ -329,8 +329,6 @@ class Packet : public Printable
     uint16_t bytesValidEnd;
 
   public:
-    /// Used to calculate latencies for each packet.
-    Tick time;
 
     /// The time at which the packet will be fully transmitted
     Tick finishTime;
@@ -585,7 +583,7 @@ class Packet : public Printable
         :  cmd(_cmd), req(_req), data(NULL),
            src(InvalidPortID), dest(InvalidPortID),
            bytesValidStart(0), bytesValidEnd(0),
-           time(curTick()), senderState(NULL)
+           senderState(NULL)
     {
         if (req->hasPaddr()) {
             addr = req->getPaddr();
@@ -606,7 +604,7 @@ class Packet : public Printable
         :  cmd(_cmd), req(_req), data(NULL),
            src(InvalidPortID), dest(InvalidPortID),
            bytesValidStart(0), bytesValidEnd(0),
-           time(curTick()), senderState(NULL)
+           senderState(NULL)
     {
         if (req->hasPaddr()) {
             addr = req->getPaddr() & ~(_blkSize - 1);
@@ -628,7 +626,7 @@ class Packet : public Printable
            data(pkt->flags.isSet(STATIC_DATA) ? pkt->data : NULL),
            addr(pkt->addr), size(pkt->size), src(pkt->src), dest(pkt->dest),
            bytesValidStart(pkt->bytesValidStart), bytesValidEnd(pkt->bytesValidEnd),
-           time(curTick()), senderState(pkt->senderState)
+           senderState(pkt->senderState)
     {
         if (!clearFlags)
             flags.set(pkt->flags & COPY_FLAGS);
@@ -665,7 +663,6 @@ class Packet : public Printable
         flags = 0;
         addr = req->getPaddr();
         size = req->getSize();
-        time = req->time();
 
         flags.set(VALID_ADDR|VALID_SIZE);
         deleteData();