changeset 7a48916a32a8 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=7a48916a32a8
description:
        Branch predictor: Fixes the tournament branch predictor.

        Branch predictor could not predict a branch in a nested loop because:
         1. The global history was not updated after a mispredict squash.
         2. The global history was updated in the fetch stage. The choice 
predictors
            that were updated  used the changed global history. This is 
incorrect, as
            it incorporates the state of global history after the branch in
            encountered. Fixed update to choice predictor using the global 
history
            state before the branch happened.
         3. The global predictor table was also updated using the global 
history state
            before the branch happened as above.

        Additionally, parameters to initialize ctr and history size were 
reversed.

diffstat:

 src/cpu/pred/tournament.cc |  55 +++++++++++++++++++++++++++++++--------------
 1 files changed, 38 insertions(+), 17 deletions(-)

diffs (85 lines):

diff -r 80492ae5148e -r 7a48916a32a8 src/cpu/pred/tournament.cc
--- a/src/cpu/pred/tournament.cc        Sun Jul 10 12:56:08 2011 -0500
+++ b/src/cpu/pred/tournament.cc        Sun Jul 10 12:56:08 2011 -0500
@@ -36,8 +36,8 @@
                            unsigned _localHistoryTableSize,
                            unsigned _localHistoryBits,
                            unsigned _globalPredictorSize,
+                           unsigned _globalHistoryBits,
                            unsigned _globalCtrBits,
-                           unsigned _globalHistoryBits,
                            unsigned _choicePredictorSize,
                            unsigned _choiceCtrBits,
                            unsigned _instShiftAmt)
@@ -247,12 +247,47 @@
             // decerement the counter.  Otherwise increment the
             // counter.
             if (history->localPredTaken == taken) {
-                choiceCtrs[globalHistory].decrement();
+                choiceCtrs[history->globalHistory].decrement();
             } else if (history->globalPredTaken == taken){
-                choiceCtrs[globalHistory].increment();
+                choiceCtrs[history->globalHistory].increment();
             }
+
         }
 
+        // Update the counters and local history with the proper
+        // resolution of the branch.  Global history is updated
+        // speculatively and restored upon squash() calls, so it does not
+        // need to be updated.
+        if (taken) {
+               localCtrs[local_predictor_idx].increment();
+               globalCtrs[history->globalHistory].increment();
+
+               updateLocalHistTaken(local_history_idx);
+        } else {
+               localCtrs[local_predictor_idx].decrement();
+               globalCtrs[history->globalHistory].decrement();
+
+               updateLocalHistNotTaken(local_history_idx);
+       }
+
+       bool mispredict = false;
+
+       //global predictor used and mispredicted
+       if (history->globalUsed && history->globalPredTaken != taken)
+           mispredict = true;
+       //local predictor used and mispredicted
+       else if (!history->globalUsed && history->localPredTaken != taken)
+           mispredict = true;
+
+       if (mispredict) {
+           if (taken) {
+              globalHistory = globalHistory | 1;
+           } else {
+              unsigned mask = globalHistoryMask - 1;
+              globalHistory = globalHistory & mask;
+           }
+
+        }
         // We're done with this history, now delete it.
         delete history;
     }
@@ -261,21 +296,7 @@
            local_history_idx < localHistoryTableSize &&
            local_predictor_idx < localPredictorSize);
 
-    // Update the counters and local history with the proper
-    // resolution of the branch.  Global history is updated
-    // speculatively and restored upon squash() calls, so it does not
-    // need to be updated.
-    if (taken) {
-        localCtrs[local_predictor_idx].increment();
-        globalCtrs[globalHistory].increment();
 
-        updateLocalHistTaken(local_history_idx);
-    } else {
-        localCtrs[local_predictor_idx].decrement();
-        globalCtrs[globalHistory].decrement();
-
-        updateLocalHistNotTaken(local_history_idx);
-    }
 }
 
 void
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to