X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fcache%2Fprefetch%2Fbase.hh;h=77d2f3697e87ebb9619a2c41ac8fe8da22efdda2;hb=7e19b26f503435f07dc4b5675061facc521b8c91;hp=fc027cb3beb4fc7440b48ad59073b1263f77edaf;hpb=d080581db1f9ee4e1e6d07d2b01c13c67908a391;p=gem5.git diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh index fc027cb3b..77d2f3697 100644 --- a/src/mem/cache/prefetch/base.hh +++ b/src/mem/cache/prefetch/base.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2013-2014 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. * @@ -26,6 +38,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ron Dreslinski + * Mitch Hayenga */ /** @@ -33,108 +46,342 @@ * Miss and writeback queue declarations. */ -#ifndef __MEM_CACHE_PREFETCH_BASE_PREFETCHER_HH__ -#define __MEM_CACHE_PREFETCH_BASE_PREFETCHER_HH__ +#ifndef __MEM_CACHE_PREFETCH_BASE_HH__ +#define __MEM_CACHE_PREFETCH_BASE_HH__ -#include +#include +#include "arch/isa_traits.hh" +#include "arch/generic/tlb.hh" #include "base/statistics.hh" +#include "base/types.hh" #include "mem/packet.hh" -#include "params/BaseCache.hh" +#include "mem/request.hh" +#include "sim/byteswap.hh" +#include "sim/clocked_object.hh" +#include "sim/probe/probe.hh" class BaseCache; +struct BasePrefetcherParams; -class BasePrefetcher +class BasePrefetcher : public ClockedObject { - protected: + class PrefetchListener : public ProbeListenerArgBase + { + public: + PrefetchListener(BasePrefetcher &_parent, ProbeManager *pm, + const std::string &name, bool _isFill = false, + bool _miss = false) + : ProbeListenerArgBase(pm, name), + parent(_parent), isFill(_isFill), miss(_miss) {} + void notify(const PacketPtr &pkt) override; + protected: + BasePrefetcher &parent; + const bool isFill; + const bool miss; + }; + + std::vector listeners; - /** The Prefetch Queue. */ - std::list pf; + public: - // PARAMETERS + /** + * Class containing the information needed by the prefetch to train and + * generate new prefetch requests. + */ + class PrefetchInfo { + /** The address used to train and generate prefetches */ + Addr address; + /** The program counter that generated this address. */ + Addr pc; + /** The requestor ID that generated this address. */ + MasterID masterId; + /** Validity bit for the PC of this address. */ + bool validPC; + /** Whether this address targets the secure memory space. */ + bool secure; + /** Size in bytes of the request triggering this event */ + unsigned int size; + /** Whether this event comes from a write request */ + bool write; + /** Physical address, needed because address can be virtual */ + Addr paddress; + /** Whether this event comes from a cache miss */ + bool cacheMiss; + /** Pointer to the associated request data */ + uint8_t *data; + + public: + /** + * Obtains the address value of this Prefetcher address. + * @return the addres value. + */ + Addr getAddr() const + { + return address; + } + + /** + * Returns true if the address targets the secure memory space. + * @return true if the address targets the secure memory space. + */ + bool isSecure() const + { + return secure; + } + + /** + * Returns the program counter that generated this request. + * @return the pc value + */ + Addr getPC() const + { + assert(hasPC()); + return pc; + } + + /** + * Returns true if the associated program counter is valid + * @return true if the program counter has a valid value + */ + bool hasPC() const + { + return validPC; + } + + /** + * Gets the requestor ID that generated this address + * @return the requestor ID that generated this address + */ + MasterID getMasterId() const + { + return masterId; + } + + /** + * Gets the size of the request triggering this event + * @return the size in bytes of the request triggering this event + */ + unsigned int getSize() const + { + return size; + } + + /** + * Checks if the request that caused this prefetch event was a write + * request + * @return true if the request causing this event is a write request + */ + bool isWrite() const + { + return write; + } + + /** + * Gets the physical address of the request + * @return physical address of the request + */ + Addr getPaddr() const + { + return paddress; + } + + /** + * Check if this event comes from a cache miss + * @result true if this event comes from a cache miss + */ + bool isCacheMiss() const + { + return cacheMiss; + } + + /** + * Gets the associated data of the request triggering the event + * @param Byte ordering of the stored data + * @return the data + */ + template + inline T + get(ByteOrder endian) const + { + if (data == nullptr) { + panic("PrefetchInfo::get called with a request with no data."); + } + switch (endian) { + case BigEndianByteOrder: + return betoh(*(T*)data); + + case LittleEndianByteOrder: + return letoh(*(T*)data); + + default: + panic("Illegal byte order in PrefetchInfo::get()\n"); + }; + } + + /** + * Check for equality + * @param pfi PrefetchInfo to compare against + * @return True if this object and the provided one are equal + */ + bool sameAddr(PrefetchInfo const &pfi) const + { + return this->getAddr() == pfi.getAddr() && + this->isSecure() == pfi.isSecure(); + } + + /** + * Constructs a PrefetchInfo using a PacketPtr. + * @param pkt PacketPtr used to generate the PrefetchInfo + * @param addr the address value of the new object, this address is + * used to train the prefetcher + * @param miss whether this event comes from a cache miss + */ + PrefetchInfo(PacketPtr pkt, Addr addr, bool miss); + + /** + * Constructs a PrefetchInfo using a new address value and + * another PrefetchInfo as a reference. + * @param pfi PrefetchInfo used to generate this new object + * @param addr the address value of the new object + */ + PrefetchInfo(PrefetchInfo const &pfi, Addr addr); + + ~PrefetchInfo() + { + delete[] data; + } + }; - /** The number of MSHRs in the Prefetch Queue. */ - const int size; + protected: + + // PARAMETERS /** Pointr to the parent cache. */ BaseCache* cache; /** The block size of the parent cache. */ - int blkSize; + unsigned blkSize; - /** Do we prefetch across page boundaries. */ - bool pageStop; + /** log_2(block size of the parent cache). */ + unsigned lBlkSize; - /** Do we remove prefetches with later times than a new miss.*/ - bool serialSquash; + /** Only consult prefetcher on cache misses? */ + const bool onMiss; - /** Do we check if it is in the cache when inserting into buffer, - or removing.*/ - bool cacheCheckPush; + /** Consult prefetcher on reads? */ + const bool onRead; - /** Do we prefetch on only data reads, or on inst reads as well. */ - bool onlyData; + /** Consult prefetcher on reads? */ + const bool onWrite; - std::string _name; + /** Consult prefetcher on data accesses? */ + const bool onData; - public: + /** Consult prefetcher on instruction accesses? */ + const bool onInst; + + /** Request id for prefetches */ + const MasterID masterId; + + const Addr pageBytes; + + /** Prefetch on every access, not just misses */ + const bool prefetchOnAccess; + + /** Use Virtual Addresses for prefetching */ + const bool useVirtualAddresses; + + /** + * Determine if this access should be observed + * @param pkt The memory request causing the event + * @param miss whether this event comes from a cache miss + */ + bool observeAccess(const PacketPtr &pkt, bool miss) const; + + /** Determine if address is in cache */ + bool inCache(Addr addr, bool is_secure) const; + + /** Determine if address is in cache miss queue */ + bool inMissQueue(Addr addr, bool is_secure) const; + + bool hasBeenPrefetched(Addr addr, bool is_secure) const; + + /** Determine if addresses are on the same page */ + bool samePage(Addr a, Addr b) const; + /** Determine the address of the block in which a lays */ + Addr blockAddress(Addr a) const; + /** Determine the address of a at block granularity */ + Addr blockIndex(Addr a) const; + /** Determine the address of the page in which a lays */ + Addr pageAddress(Addr a) const; + /** Determine the page-offset of a */ + Addr pageOffset(Addr a) const; + /** Build the address of the i-th block inside the page */ + Addr pageIthBlockAddress(Addr page, uint32_t i) const; - Stats::Scalar pfIdentified; - Stats::Scalar pfMSHRHit; - Stats::Scalar pfCacheHit; - Stats::Scalar pfBufferHit; - Stats::Scalar pfRemovedFull; - Stats::Scalar pfRemovedMSHR; Stats::Scalar pfIssued; - Stats::Scalar pfSpanPage; - Stats::Scalar pfSquashed; - void regStats(const std::string &name); + /** Total prefetches issued */ + uint64_t issuedPrefetches; + /** Total prefetches that has been useful */ + uint64_t usefulPrefetches; + + /** Registered tlb for address translations */ + BaseTLB * tlb; public: - BasePrefetcher(const BaseCacheParams *p); + BasePrefetcher(const BasePrefetcherParams *p); virtual ~BasePrefetcher() {} - const std::string name() const { return _name; } - - void setCache(BaseCache *_cache); + virtual void setCache(BaseCache *_cache); /** * Notify prefetcher of cache access (may be any access or just * misses, depending on cache parameters.) - * @retval Time of next prefetch availability, or 0 if none. */ - Tick notify(PacketPtr &pkt, Tick time); + virtual void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) = 0; - bool inCache(Addr addr); + /** Notify prefetcher of cache fill */ + virtual void notifyFill(const PacketPtr &pkt) + {} - bool inMissQueue(Addr addr); + virtual PacketPtr getPacket() = 0; - PacketPtr getPacket(); + virtual Tick nextPrefetchReadyTime() const = 0; - bool havePending() - { - return !pf.empty(); - } + /** + * Register local statistics. + */ + void regStats() override; - Tick nextPrefetchReadyTime() - { - return pf.empty() ? MaxTick : pf.front()->time; - } + /** + * Register probe points for this object. + */ + void regProbeListeners() override; - virtual void calculatePrefetch(PacketPtr &pkt, - std::list &addresses, - std::list &delays) = 0; + /** + * Process a notification event from the ProbeListener. + * @param pkt The memory request causing the event + * @param miss whether this event comes from a cache miss + */ + void probeNotify(const PacketPtr &pkt, bool miss); - std::list::iterator inPrefetch(Addr address); + /** + * Add a SimObject and a probe name to listen events from + * @param obj The SimObject pointer to listen from + * @param name The probe name + */ + void addEventProbe(SimObject *obj, const char *name); /** - * Utility function: are addresses a and b on the same VM page? + * Add a BaseTLB object to be used whenever a translation is needed. + * This is generally required when the prefetcher is allowed to generate + * page crossing references and/or uses virtual addresses for training. + * @param tlb pointer to the BaseTLB object to add */ - bool samePage(Addr a, Addr b); + void addTLB(BaseTLB *tlb); }; - - -#endif //__MEM_CACHE_PREFETCH_BASE_PREFETCHER_HH__ +#endif //__MEM_CACHE_PREFETCH_BASE_HH__