Added a mechanism to control the number of prefetches generated based in the effectiveness of the prefetches generated so far. Change-Id: I33af82546f74a5b5ab372c28574b76dd9a1bd46a Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18808 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
251 lines
9.1 KiB
C++
251 lines
9.1 KiB
C++
/*
|
|
* Copyright (c) 2014-2015 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.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Authors: Mitch Hayenga
|
|
*/
|
|
|
|
#ifndef __MEM_CACHE_PREFETCH_QUEUED_HH__
|
|
#define __MEM_CACHE_PREFETCH_QUEUED_HH__
|
|
|
|
#include <cstdint>
|
|
#include <list>
|
|
#include <utility>
|
|
|
|
#include "base/statistics.hh"
|
|
#include "base/types.hh"
|
|
#include "mem/cache/prefetch/base.hh"
|
|
#include "mem/packet.hh"
|
|
|
|
struct QueuedPrefetcherParams;
|
|
|
|
class QueuedPrefetcher : public BasePrefetcher
|
|
{
|
|
protected:
|
|
struct DeferredPacket : public BaseTLB::Translation {
|
|
/** Owner of the packet */
|
|
QueuedPrefetcher *owner;
|
|
/** Prefetch info corresponding to this packet */
|
|
PrefetchInfo pfInfo;
|
|
/** Time when this prefetch becomes ready */
|
|
Tick tick;
|
|
/** The memory packet generated by this prefetch */
|
|
PacketPtr pkt;
|
|
/** The priority of this prefetch */
|
|
int32_t priority;
|
|
/** Request used when a translation is needed */
|
|
RequestPtr translationRequest;
|
|
ThreadContext *tc;
|
|
bool ongoingTranslation;
|
|
|
|
/**
|
|
* Constructor
|
|
* @param o QueuedPrefetcher in charge of this request
|
|
* @param pfi PrefechInfo object associated to this packet
|
|
* @param t Time when this prefetch becomes ready
|
|
* @param p PacketPtr with the memory request of the prefetch
|
|
* @param prio This prefetch priority
|
|
*/
|
|
DeferredPacket(QueuedPrefetcher *o, PrefetchInfo const &pfi, Tick t,
|
|
int32_t prio) : owner(o), pfInfo(pfi), tick(t), pkt(nullptr),
|
|
priority(prio), translationRequest() {
|
|
}
|
|
|
|
bool operator>(const DeferredPacket& that) const
|
|
{
|
|
return priority > that.priority;
|
|
}
|
|
bool operator<(const DeferredPacket& that) const
|
|
{
|
|
return priority < that.priority;
|
|
}
|
|
bool operator<=(const DeferredPacket& that) const
|
|
{
|
|
return !(*this > that);
|
|
}
|
|
|
|
/**
|
|
* Create the associated memory packet
|
|
* @param paddr physical address of this packet
|
|
* @param blk_size block size used by the prefetcher
|
|
* @param mid Requester ID of the access that generated this prefetch
|
|
* @param tag_prefetch flag to indicate if the packet needs to be
|
|
* tagged
|
|
* @param t time when the prefetch becomes ready
|
|
*/
|
|
void createPkt(Addr paddr, unsigned blk_size, MasterID mid,
|
|
bool tag_prefetch, Tick t);
|
|
|
|
/**
|
|
* Sets the translation request needed to obtain the physical address
|
|
* of this request.
|
|
* @param req The Request with the virtual address of this request
|
|
*/
|
|
void setTranslationRequest(const RequestPtr &req)
|
|
{
|
|
translationRequest = req;
|
|
}
|
|
|
|
void markDelayed() override
|
|
{}
|
|
|
|
void finish(const Fault &fault, const RequestPtr &req,
|
|
ThreadContext *tc, BaseTLB::Mode mode) override;
|
|
|
|
/**
|
|
* Issues the translation request to the provided TLB
|
|
* @param tlb the tlb that has to translate the address
|
|
*/
|
|
void startTranslation(BaseTLB *tlb);
|
|
};
|
|
|
|
std::list<DeferredPacket> pfq;
|
|
std::list<DeferredPacket> pfqMissingTranslation;
|
|
|
|
using const_iterator = std::list<DeferredPacket>::const_iterator;
|
|
using iterator = std::list<DeferredPacket>::iterator;
|
|
|
|
// PARAMETERS
|
|
|
|
/** Maximum size of the prefetch queue */
|
|
const unsigned queueSize;
|
|
|
|
/**
|
|
* Maximum size of the queue holding prefetch requests with missing
|
|
* address translations
|
|
*/
|
|
const unsigned missingTranslationQueueSize;
|
|
|
|
/** Cycles after generation when a prefetch can first be issued */
|
|
const Cycles latency;
|
|
|
|
/** Squash queued prefetch if demand access observed */
|
|
const bool queueSquash;
|
|
|
|
/** Filter prefetches if already queued */
|
|
const bool queueFilter;
|
|
|
|
/** Snoop the cache before generating prefetch (cheating basically) */
|
|
const bool cacheSnoop;
|
|
|
|
/** Tag prefetch with PC of generating access? */
|
|
const bool tagPrefetch;
|
|
|
|
/** Percentage of requests that can be throttled */
|
|
const unsigned int throttleControlPct;
|
|
|
|
// STATS
|
|
Stats::Scalar pfIdentified;
|
|
Stats::Scalar pfBufferHit;
|
|
Stats::Scalar pfInCache;
|
|
Stats::Scalar pfRemovedFull;
|
|
Stats::Scalar pfSpanPage;
|
|
|
|
public:
|
|
using AddrPriority = std::pair<Addr, int32_t>;
|
|
|
|
QueuedPrefetcher(const QueuedPrefetcherParams *p);
|
|
virtual ~QueuedPrefetcher();
|
|
|
|
void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) override;
|
|
|
|
void insert(const PacketPtr &pkt, PrefetchInfo &new_pfi, int32_t priority);
|
|
|
|
virtual void calculatePrefetch(const PrefetchInfo &pfi,
|
|
std::vector<AddrPriority> &addresses) = 0;
|
|
PacketPtr getPacket() override;
|
|
|
|
Tick nextPrefetchReadyTime() const override
|
|
{
|
|
return pfq.empty() ? MaxTick : pfq.front().tick;
|
|
}
|
|
|
|
void regStats() override;
|
|
|
|
private:
|
|
|
|
/**
|
|
* Adds a DeferredPacket to the specified queue
|
|
* @param queue selected queue to use
|
|
* @param dpp DeferredPacket to add
|
|
*/
|
|
void addToQueue(std::list<DeferredPacket> &queue, DeferredPacket &dpp);
|
|
|
|
/**
|
|
* Starts the translations of the queued prefetches with a
|
|
* missing translation. It performs a maximum specified number of
|
|
* translations. Successful translations cause the prefetch request to be
|
|
* queued in the queue of ready requests.
|
|
* @param max maximum number of translations to perform
|
|
*/
|
|
void processMissingTranslations(unsigned max);
|
|
|
|
/**
|
|
* Indicates that the translation of the address of the provided deferred
|
|
* packet has been successfully completed, and it can be enqueued as a
|
|
* new prefetch request.
|
|
* @param dp the deferred packet that has completed the translation request
|
|
* @param failed whether the translation was successful
|
|
*/
|
|
void translationComplete(DeferredPacket *dp, bool failed);
|
|
|
|
/**
|
|
* Checks whether the specified prefetch request is already in the
|
|
* specified queue. If the request is found, its priority is updated.
|
|
* @param queue selected queue to check
|
|
* @param pfi information of the prefetch request to be added
|
|
* @param priority priority of the prefetch request to be added
|
|
* @return True if the prefetch request was found in the queue
|
|
*/
|
|
bool alreadyInQueue(std::list<DeferredPacket> &queue,
|
|
const PrefetchInfo &pfi, int32_t priority);
|
|
|
|
/**
|
|
* Returns the maxmimum number of prefetch requests that are allowed
|
|
* to be created from the number of prefetch candidates provided.
|
|
* The behavior of this service is controlled with the throttleControlPct
|
|
* parameter.
|
|
* @param total number of prefetch candidates generated by the prefetcher
|
|
* @return the number of these request candidates are allowed to be created
|
|
*/
|
|
size_t getMaxPermittedPrefetches(size_t total) const;
|
|
|
|
RequestPtr createPrefetchRequest(Addr addr, PrefetchInfo const &pfi,
|
|
PacketPtr pkt);
|
|
};
|
|
|
|
#endif //__MEM_CACHE_PREFETCH_QUEUED_HH__
|
|
|