LSQ: Set store predictor to periodically clear itself as recommended in the storesets...
authorAli Saidi <Ali.Saidi@ARM.com>
Fri, 19 Aug 2011 20:08:07 +0000 (15:08 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Fri, 19 Aug 2011 20:08:07 +0000 (15:08 -0500)
This patch improves performance by as much as 10% on some spec benchmarks.

src/cpu/o3/O3CPU.py
src/cpu/o3/mem_dep_unit_impl.hh
src/cpu/o3/store_set.cc
src/cpu/o3/store_set.hh

index f379fcd8a5eb833a1ac9dec8d4e824c1b3a82453..47b18a3ecdce4e2df0d3c8083d819879b52bab7d 100644 (file)
@@ -121,6 +121,8 @@ class DerivO3CPU(BaseCPU):
     LSQDepCheckShift = Param.Unsigned(4, "Number of places to shift addr before check")
     LSQCheckLoads = Param.Bool(True,
         "Should dependency violations be checked for loads & stores or just stores")
+    store_set_clear_period = Param.Unsigned(250000,
+            "Number of load/store insts before the dep predictor should be invalidated")
     LFSTSize = Param.Unsigned(1024, "Last fetched store table size")
     SSITSize = Param.Unsigned(1024, "Store set ID table size")
 
index 0208a622e3640df5b86d6688a5849c5b5691ba53..d30dcbd3d4f17e974cd4def6d1786fabea12a24a 100644 (file)
@@ -45,8 +45,10 @@ MemDepUnit<MemDepPred, Impl>::MemDepUnit()
 template <class MemDepPred, class Impl>
 MemDepUnit<MemDepPred, Impl>::MemDepUnit(DerivO3CPUParams *params)
     : _name(params->name + ".memdepunit"),
-      depPred(params->SSITSize, params->LFSTSize), loadBarrier(false),
-      loadBarrierSN(0), storeBarrier(false), storeBarrierSN(0), iqPtr(NULL)
+      depPred(params->store_set_clear_period, params->SSITSize,
+              params->LFSTSize),
+      loadBarrier(false), loadBarrierSN(0), storeBarrier(false),
+      storeBarrierSN(0), iqPtr(NULL)
 {
     DPRINTF(MemDepUnit, "Creating MemDepUnit object.\n");
 }
@@ -85,7 +87,8 @@ MemDepUnit<MemDepPred, Impl>::init(DerivO3CPUParams *params, ThreadID tid)
     _name = csprintf("%s.memDep%d", params->name, tid);
     id = tid;
 
-    depPred.init(params->SSITSize, params->LFSTSize);
+    depPred.init(params->store_set_clear_period, params->SSITSize,
+            params->LFSTSize);
 }
 
 template <class MemDepPred, class Impl>
index fc87c417ecb0f7dcf86df201b085d30caa52cd1d..acd4a8d0a5cd985818ca972d042c932723a5889a 100644 (file)
@@ -34,8 +34,8 @@
 #include "cpu/o3/store_set.hh"
 #include "debug/StoreSet.hh"
 
-StoreSet::StoreSet(int _SSIT_size, int _LFST_size)
-    : SSITSize(_SSIT_size), LFSTSize(_LFST_size)
+StoreSet::StoreSet(uint64_t clear_period, int _SSIT_size, int _LFST_size)
+    : clearPeriod(clear_period), SSITSize(_SSIT_size), LFSTSize(_LFST_size)
 {
     DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
     DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
@@ -68,6 +68,8 @@ StoreSet::StoreSet(int _SSIT_size, int _LFST_size)
     indexMask = SSITSize - 1;
 
     offsetBits = 2;
+
+    memOpsPred = 0;
 }
 
 StoreSet::~StoreSet()
@@ -75,10 +77,11 @@ StoreSet::~StoreSet()
 }
 
 void
-StoreSet::init(int _SSIT_size, int _LFST_size)
+StoreSet::init(uint64_t clear_period, int _SSIT_size, int _LFST_size)
 {
     SSITSize = _SSIT_size;
     LFSTSize = _LFST_size;
+    clearPeriod = clear_period;
 
     DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
     DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
@@ -103,6 +106,8 @@ StoreSet::init(int _SSIT_size, int _LFST_size)
     indexMask = SSITSize - 1;
 
     offsetBits = 2;
+
+    memOpsPred = 0;
 }
 
 
@@ -179,9 +184,22 @@ StoreSet::violation(Addr store_PC, Addr load_PC)
     }
 }
 
+void
+StoreSet::checkClear()
+{
+    memOpsPred++;
+    if (memOpsPred > clearPeriod) {
+        DPRINTF(StoreSet, "Wiping predictor state beacuse %d ld/st executed\n",
+                clearPeriod);
+        memOpsPred = 0;
+        clear();
+    }
+}
+
 void
 StoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num)
 {
+    checkClear();
     // Does nothing.
     return;
 }
@@ -193,6 +211,7 @@ StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num, ThreadID tid)
 
     int store_SSID;
 
+    checkClear();
     assert(index < SSITSize);
 
     if (!validSSIT[index]) {
index ce4591f68fe45ef43d784ad71aed6ea7d849bb9e..973b83b42d68afc812be8b54b0599ca6e92ba6ba 100644 (file)
@@ -63,18 +63,24 @@ class StoreSet
     StoreSet() { };
 
     /** Creates store set predictor with given table sizes. */
-    StoreSet(int SSIT_size, int LFST_size);
+    StoreSet(uint64_t clear_period, int SSIT_size, int LFST_size);
 
     /** Default destructor. */
     ~StoreSet();
 
     /** Initializes the store set predictor with the given table sizes. */
-    void init(int SSIT_size, int LFST_size);
+    void init(uint64_t clear_period, int SSIT_size, int LFST_size);
 
     /** Records a memory ordering violation between the younger load
      * and the older store. */
     void violation(Addr store_PC, Addr load_PC);
 
+    /** Clears the store set predictor every so often so that all the
+     * entries aren't used and stores are constantly predicted as
+     * conflicting.
+     */
+    void checkClear();
+
     /** Inserts a load into the store set predictor.  This does nothing but
      * is included in case other predictors require a similar function.
      */
@@ -130,6 +136,11 @@ class StoreSet
 
     typedef std::map<InstSeqNum, int, ltseqnum>::iterator SeqNumMapIt;
 
+    /** Number of loads/stores to process before wiping predictor so all
+     * entries don't get saturated
+     */
+    uint64_t clearPeriod;
+
     /** Store Set ID Table size, in entries. */
     int SSITSize;
 
@@ -141,6 +152,9 @@ class StoreSet
 
     // HACK: Hardcoded for now.
     int offsetBits;
+
+    /** Number of memory operations predicted since last clear of predictor */
+    int memOpsPred;
 };
 
 #endif // __CPU_O3_STORE_SET_HH__