summaryrefslogtreecommitdiff
path: root/src/mem/dram_ctrl.hh
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2015-07-03 10:14:45 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2015-07-03 10:14:45 -0400
commitb56167b68214581857ffae5c25f7945d75cee6b3 (patch)
treec0d9d30d659a8e8bd6d27b9a4bcbd4438e413025 /src/mem/dram_ctrl.hh
parentdb85ddca1a3c81fb7c513216fa08bb1f6dd580b7 (diff)
downloadgem5-b56167b68214581857ffae5c25f7945d75cee6b3.tar.xz
mem: Avoid DRAM write queue iteration for merging and read lookup
This patch adds a simple lookup structure to avoid iterating over the write queue to find read matches, and for the merging of write bursts. Instead of relying on iteration we simply store a set of currently-buffered write-burst addresses and compare against these. For the reads we still perform the iteration if we have a match. For the writes, we rely entirely on the set. Note that there are corner-cases where sub-bursts would actually not be mergeable without a read-modify-write. We ignore these cases and opt for speed.
Diffstat (limited to 'src/mem/dram_ctrl.hh')
-rw-r--r--src/mem/dram_ctrl.hh21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/mem/dram_ctrl.hh b/src/mem/dram_ctrl.hh
index 3caaff959..57731f5e0 100644
--- a/src/mem/dram_ctrl.hh
+++ b/src/mem/dram_ctrl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 ARM Limited
+ * Copyright (c) 2012-2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -53,6 +53,7 @@
#include <deque>
#include <string>
+#include <unordered_set>
#include "base/statistics.hh"
#include "enums/AddrMap.hh"
@@ -637,12 +638,30 @@ class DRAMCtrl : public AbstractMemory
void printQs() const;
/**
+ * Burst-align an address.
+ *
+ * @param addr The potentially unaligned address
+ *
+ * @return An address aligned to a DRAM burst
+ */
+ Addr burstAlign(Addr addr) const { return (addr & ~(Addr(burstSize - 1))); }
+
+ /**
* The controller's main read and write queues
*/
std::deque<DRAMPacket*> readQueue;
std::deque<DRAMPacket*> writeQueue;
/**
+ * To avoid iterating over the write queue to check for
+ * overlapping transactions, maintain a set of burst addresses
+ * that are currently queued. Since we merge writes to the same
+ * location we never have more than one address to the same burst
+ * address.
+ */
+ std::unordered_set<Addr> isInWriteQueue;
+
+ /**
* Response queue where read packets wait after we're done working
* with them, but it's not time to send the response yet. The
* responses are stored seperately mostly to keep the code clean