From 362160c8aeeb5b655158061ad57404124b4618f3 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 19 Feb 2013 05:56:06 -0500 Subject: [PATCH] mem: Add deferred packet class to prefetcher 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 | 47 +++++++++++++++++++++------------- src/mem/cache/prefetch/base.hh | 30 +++++++++++++++++++--- src/mem/packet.hh | 9 +++---- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc index ddf1c1b31..6463f78f8 100644 --- a/src/mem/cache/prefetch/base.cc +++ b/src/mem/cache/prefetch/base.cc @@ -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::iterator iter = inPrefetch(blk_addr); + std::list::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::iterator +std::list::iterator BasePrefetcher::inPrefetch(Addr address) { // Guaranteed to only be one match, we always check before inserting - std::list::iterator iter; + std::list::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; } } diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index 99385c1c1..07ca3dd6f 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -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 pf; + std::list 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 &addresses, std::list &delays) = 0; - std::list::iterator inPrefetch(Addr address); + std::list::iterator inPrefetch(Addr address); /** * Utility function: are addresses a and b on the same VM page? diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 6d9e88b8f..181320850 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -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(); -- 2.30.2