cpu: Fix BTB threading oversight
authorMitch Hayenga <mitch.hayenga@arm.com>
Tue, 5 Apr 2016 16:44:27 +0000 (11:44 -0500)
committerMitch Hayenga <mitch.hayenga@arm.com>
Tue, 5 Apr 2016 16:44:27 +0000 (11:44 -0500)
The extant BTB code doesn't hash on the thread id but does check the
thread id for 'btb hits'.  This results in 1-thread of a multi-threaded
workload taking a BTB entry, and all other threads missing for the same branch
missing.

src/cpu/pred/bpred_unit.cc
src/cpu/pred/btb.cc
src/cpu/pred/btb.hh

index 8bb84f836b6953e9cc039fe7693e51fdf14416c6..c38927c8dac7f57217c12ed52f6b90762a91cfd0 100644 (file)
@@ -59,7 +59,8 @@ BPredUnit::BPredUnit(const Params *params)
       predHist(numThreads),
       BTB(params->BTBEntries,
           params->BTBTagSize,
-          params->instShiftAmt),
+          params->instShiftAmt,
+          params->numThreads),
       RAS(numThreads),
       instShiftAmt(params->instShiftAmt)
 {
index 393e52ccf80bca56945bac85803cecd519336ab5..c7ef1959fc004ed837c6e74ec806814addcfbf41 100644 (file)
 
 DefaultBTB::DefaultBTB(unsigned _numEntries,
                        unsigned _tagBits,
-                       unsigned _instShiftAmt)
+                       unsigned _instShiftAmt,
+                       unsigned _num_threads)
     : numEntries(_numEntries),
       tagBits(_tagBits),
-      instShiftAmt(_instShiftAmt)
+      instShiftAmt(_instShiftAmt),
+      log2NumThreads(floorLog2(_num_threads))
 {
     DPRINTF(Fetch, "BTB: Creating BTB object.\n");
 
@@ -69,10 +71,12 @@ DefaultBTB::reset()
 
 inline
 unsigned
-DefaultBTB::getIndex(Addr instPC)
+DefaultBTB::getIndex(Addr instPC, ThreadID tid)
 {
     // Need to shift PC over by the word offset.
-    return (instPC >> instShiftAmt) & idxMask;
+    return ((instPC >> instShiftAmt)
+            ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads)))
+            & idxMask;
 }
 
 inline
@@ -85,7 +89,7 @@ DefaultBTB::getTag(Addr instPC)
 bool
 DefaultBTB::valid(Addr instPC, ThreadID tid)
 {
-    unsigned btb_idx = getIndex(instPC);
+    unsigned btb_idx = getIndex(instPC, tid);
 
     Addr inst_tag = getTag(instPC);
 
@@ -106,7 +110,7 @@ DefaultBTB::valid(Addr instPC, ThreadID tid)
 TheISA::PCState
 DefaultBTB::lookup(Addr instPC, ThreadID tid)
 {
-    unsigned btb_idx = getIndex(instPC);
+    unsigned btb_idx = getIndex(instPC, tid);
 
     Addr inst_tag = getTag(instPC);
 
@@ -124,7 +128,7 @@ DefaultBTB::lookup(Addr instPC, ThreadID tid)
 void
 DefaultBTB::update(Addr instPC, const TheISA::PCState &target, ThreadID tid)
 {
-    unsigned btb_idx = getIndex(instPC);
+    unsigned btb_idx = getIndex(instPC, tid);
 
     assert(btb_idx < numEntries);
 
index 3a773e40d4a9c61f05985ac2f1138807a24d4c42..209bbdb49a9963294a57ffa13103c53476bf1a59 100644 (file)
@@ -66,7 +66,7 @@ class DefaultBTB
      *  @param instShiftAmt Offset amount for instructions to ignore alignment.
      */
     DefaultBTB(unsigned numEntries, unsigned tagBits,
-               unsigned instShiftAmt);
+               unsigned instShiftAmt, unsigned numThreads);
 
     void reset();
 
@@ -97,7 +97,7 @@ class DefaultBTB
      *  @param inst_PC The branch to look up.
      *  @return Returns the index into the BTB.
      */
-    inline unsigned getIndex(Addr instPC);
+    inline unsigned getIndex(Addr instPC, ThreadID tid);
 
     /** Returns the tag bits of a given address.
      *  @param inst_PC The branch's address.
@@ -125,6 +125,9 @@ class DefaultBTB
 
     /** Number of bits to shift PC when calculating tag. */
     unsigned tagShiftAmt;
+
+    /** Log2 NumThreads used for hashing threadid */
+    unsigned log2NumThreads;
 };
 
 #endif // __CPU_PRED_BTB_HH__