diff options
Diffstat (limited to 'src/mem/cache/mshr.hh')
-rw-r--r-- | src/mem/cache/mshr.hh | 103 |
1 files changed, 100 insertions, 3 deletions
diff --git a/src/mem/cache/mshr.hh b/src/mem/cache/mshr.hh index 218de9244..56b81b6b2 100644 --- a/src/mem/cache/mshr.hh +++ b/src/mem/cache/mshr.hh @@ -38,6 +38,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Erik Hallnor + * Nikos Nikoleris */ /** @@ -52,11 +53,13 @@ #include <iosfwd> #include <list> #include <string> +#include <vector> #include "base/printable.hh" #include "base/types.hh" #include "mem/cache/queue_entry.hh" #include "mem/packet.hh" +#include "mem/request.hh" #include "sim/core.hh" class BaseCache; @@ -115,6 +118,9 @@ class MSHR : public QueueEntry, public Printable public: + /** Track if we sent this as a whole line write or not */ + bool wasWholeLineWrite; + /** True if the entry is just a simple forward from an upper level */ bool isForward; @@ -187,7 +193,24 @@ class MSHR : public QueueEntry, public Printable void updateFlags(PacketPtr pkt, Target::Source source, bool alloc_on_fill); + /** + * Reset state + * + * @param blk_addr Address of the cache block + * @param blk_size Size of the cache block + */ + void init(Addr blk_addr, Addr blk_size) { + blkAddr = blk_addr; + blkSize = blk_size; + writesBitmap.resize(blk_size); + + resetFlags(); + } + void resetFlags() { + onlyWrites = true; + std::fill(writesBitmap.begin(), writesBitmap.end(), false); + needsWritable = false; hasUpgrade = false; allocOnFill = false; @@ -203,12 +226,44 @@ class MSHR : public QueueEntry, public Printable void populateFlags(); /** + * Add the specified packet in the TargetList. This function + * stores information related to the added packet and updates + * accordingly the flags. + * + * @param pkt Packet considered for adding + */ + void updateWriteFlags(PacketPtr pkt) { + const Request::FlagsType noMergeFlags = + Request::UNCACHEABLE | + Request::STRICT_ORDER | Request::MMAPPED_IPR | + Request::PRIVILEGED | Request::LLSC | + Request::MEM_SWAP | Request::MEM_SWAP_COND | + Request::SECURE; + + // if we have already seen writes for the full block stop + // here, this might be a full line write followed by + // other compatible requests (e.g., reads) + if (!isWholeLineWrite()) { + bool can_merge_write = pkt->isWrite() && + ((pkt->req->getFlags() & noMergeFlags) == 0); + onlyWrites &= can_merge_write; + if (onlyWrites) { + auto offset = pkt->getOffset(blkSize); + auto begin = writesBitmap.begin() + offset; + std::fill(begin, begin + pkt->getSize(), true); + } + } + } + + /** * Tests if the flags of this TargetList have their default * values. + * + * @return True if the TargetList are reset, false otherwise. */ bool isReset() const { return !needsWritable && !hasUpgrade && !allocOnFill && - !hasFromCache; + !hasFromCache && onlyWrites; } /** @@ -224,8 +279,7 @@ class MSHR : public QueueEntry, public Printable * @param alloc_on_fill Whether it should allocate on a fill */ void add(PacketPtr pkt, Tick readyTime, Counter order, - Target::Source source, bool markPending, - bool alloc_on_fill); + Target::Source source, bool markPending, bool alloc_on_fill); /** * Convert upgrades to the equivalent request if the cache line they @@ -238,6 +292,39 @@ class MSHR : public QueueEntry, public Printable bool trySatisfyFunctional(PacketPtr pkt); void print(std::ostream &os, int verbosity, const std::string &prefix) const; + + /** + * Check if this list contains only compatible writes, and if they + * span the entire cache line. This is used as part of the + * miss-packet creation. Note that new requests may arrive after a + * miss-packet has been created, and for the fill we therefore use + * the wasWholeLineWrite field. + */ + bool isWholeLineWrite() const + { + return onlyWrites && + std::all_of(writesBitmap.begin(), + writesBitmap.end(), [](bool i) { return i; }); + } + + private: + /** Address of the cache block for this list of targets. */ + Addr blkAddr; + + /** Size of the cache block. */ + Addr blkSize; + + /** Are we only dealing with writes. */ + bool onlyWrites; + + // NOTE: std::vector<bool> might not meet satisfy the + // ForwardIterator requirement and therefore cannot be used + // for writesBitmap. + /** + * Track which bytes are written by requests in this target + * list. + */ + std::vector<char> writesBitmap; }; /** A list of MSHRs. */ @@ -315,6 +402,16 @@ class MSHR : public QueueEntry, public Printable TargetList deferredTargets; public: + /** + * Check if this MSHR contains only compatible writes, and if they + * span the entire cache line. This is used as part of the + * miss-packet creation. Note that new requests may arrive after a + * miss-packet has been created, and for the fill we therefore use + * the wasWholeLineWrite field. + */ + bool isWholeLineWrite() const { + return targets.isWholeLineWrite(); + } /** * Allocate a miss to this MSHR. |