2 * Copyright (c) 2014 The University of Wisconsin
4 * Copyright (c) 2006 INRIA (Institut National de Recherche en
5 * Informatique et en Automatique / French National Research Institute
6 * for Computer Science and Applied Mathematics)
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met: redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer;
14 * redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution;
17 * neither the name of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * Implementation of a TAGE branch predictor
38 #include "cpu/pred/tage_base.hh"
40 #include "base/intmath.hh"
41 #include "base/logging.hh"
42 #include "debug/Fetch.hh"
43 #include "debug/Tage.hh"
45 TAGEBase::TAGEBase(const TAGEBaseParams
*p
)
47 logRatioBiModalHystEntries(p
->logRatioBiModalHystEntries
),
48 nHistoryTables(p
->nHistoryTables
),
49 tagTableCounterBits(p
->tagTableCounterBits
),
50 tagTableUBits(p
->tagTableUBits
),
51 histBufferSize(p
->histBufferSize
),
54 pathHistBits(p
->pathHistBits
),
55 tagTableTagWidths(p
->tagTableTagWidths
),
56 logTagTableSizes(p
->logTagTableSizes
),
57 threadHistory(p
->numThreads
),
58 logUResetPeriod(p
->logUResetPeriod
),
59 initialTCounterValue(p
->initialTCounterValue
),
60 numUseAltOnNa(p
->numUseAltOnNa
),
61 useAltOnNaBits(p
->useAltOnNaBits
),
62 maxNumAlloc(p
->maxNumAlloc
),
64 speculativeHistUpdate(p
->speculativeHistUpdate
),
65 instShiftAmt(p
->instShiftAmt
),
69 // Set all the table to enabled by default
70 noSkip
.resize(nHistoryTables
+ 1, true);
75 TAGEBase::makeBranchInfo() {
76 return new BranchInfo(*this);
85 // Current method for periodically resetting the u counter bits only
86 // works for 1 or 2 bits
87 // Also make sure that it is not 0
88 assert(tagTableUBits
<= 2 && (tagTableUBits
> 0));
90 // we use int type for the path history, so it cannot be more than
92 assert(pathHistBits
<= (sizeof(int)*8));
94 // initialize the counter to half of the period
95 assert(logUResetPeriod
!= 0);
96 tCounter
= initialTCounterValue
;
98 assert(histBufferSize
> maxHist
* 2);
100 useAltPredForNewlyAllocated
.resize(numUseAltOnNa
, 0);
102 for (auto& history
: threadHistory
) {
103 history
.pathHist
= 0;
104 history
.globalHistory
= new uint8_t[histBufferSize
];
105 history
.gHist
= history
.globalHistory
;
106 memset(history
.gHist
, 0, histBufferSize
);
110 histLengths
= new int [nHistoryTables
+1];
112 calculateParameters();
114 assert(tagTableTagWidths
.size() == (nHistoryTables
+1));
115 assert(logTagTableSizes
.size() == (nHistoryTables
+1));
117 // First entry is for the Bimodal table and it is untagged in this
119 assert(tagTableTagWidths
[0] == 0);
121 for (auto& history
: threadHistory
) {
122 history
.computeIndices
= new FoldedHistory
[nHistoryTables
+1];
123 history
.computeTags
[0] = new FoldedHistory
[nHistoryTables
+1];
124 history
.computeTags
[1] = new FoldedHistory
[nHistoryTables
+1];
126 initFoldedHistories(history
);
129 const uint64_t bimodalTableSize
= ULL(1) << logTagTableSizes
[0];
130 btablePrediction
.resize(bimodalTableSize
, false);
131 btableHysteresis
.resize(bimodalTableSize
>> logRatioBiModalHystEntries
,
134 gtable
= new TageEntry
*[nHistoryTables
+ 1];
137 tableIndices
= new int [nHistoryTables
+1];
138 tableTags
= new int [nHistoryTables
+1];
143 TAGEBase::initFoldedHistories(ThreadHistory
& history
)
145 for (int i
= 1; i
<= nHistoryTables
; i
++) {
146 history
.computeIndices
[i
].init(
147 histLengths
[i
], (logTagTableSizes
[i
]));
148 history
.computeTags
[0][i
].init(
149 history
.computeIndices
[i
].origLength
, tagTableTagWidths
[i
]);
150 history
.computeTags
[1][i
].init(
151 history
.computeIndices
[i
].origLength
, tagTableTagWidths
[i
]-1);
152 DPRINTF(Tage
, "HistLength:%d, TTSize:%d, TTTWidth:%d\n",
153 histLengths
[i
], logTagTableSizes
[i
], tagTableTagWidths
[i
]);
158 TAGEBase::buildTageTables()
160 for (int i
= 1; i
<= nHistoryTables
; i
++) {
161 gtable
[i
] = new TageEntry
[1<<(logTagTableSizes
[i
])];
166 TAGEBase::calculateParameters()
168 histLengths
[1] = minHist
;
169 histLengths
[nHistoryTables
] = maxHist
;
171 for (int i
= 2; i
<= nHistoryTables
; i
++) {
172 histLengths
[i
] = (int) (((double) minHist
*
173 pow ((double) (maxHist
) / (double) minHist
,
174 (double) (i
- 1) / (double) ((nHistoryTables
- 1))))
180 TAGEBase::btbUpdate(ThreadID tid
, Addr branch_pc
, BranchInfo
* &bi
)
182 if (speculativeHistUpdate
) {
183 ThreadHistory
& tHist
= threadHistory
[tid
];
184 DPRINTF(Tage
, "BTB miss resets prediction: %lx\n", branch_pc
);
185 assert(tHist
.gHist
== &tHist
.globalHistory
[tHist
.ptGhist
]);
187 for (int i
= 1; i
<= nHistoryTables
; i
++) {
188 tHist
.computeIndices
[i
].comp
= bi
->ci
[i
];
189 tHist
.computeTags
[0][i
].comp
= bi
->ct0
[i
];
190 tHist
.computeTags
[1][i
].comp
= bi
->ct1
[i
];
191 tHist
.computeIndices
[i
].update(tHist
.gHist
);
192 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
193 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
199 TAGEBase::bindex(Addr pc_in
) const
201 return ((pc_in
>> instShiftAmt
) & ((ULL(1) << (logTagTableSizes
[0])) - 1));
205 TAGEBase::F(int A
, int size
, int bank
) const
209 A
= A
& ((ULL(1) << size
) - 1);
210 A1
= (A
& ((ULL(1) << logTagTableSizes
[bank
]) - 1));
211 A2
= (A
>> logTagTableSizes
[bank
]);
212 A2
= ((A2
<< bank
) & ((ULL(1) << logTagTableSizes
[bank
]) - 1))
213 + (A2
>> (logTagTableSizes
[bank
] - bank
));
215 A
= ((A
<< bank
) & ((ULL(1) << logTagTableSizes
[bank
]) - 1))
216 + (A
>> (logTagTableSizes
[bank
] - bank
));
220 // gindex computes a full hash of pc, ghist and pathHist
222 TAGEBase::gindex(ThreadID tid
, Addr pc
, int bank
) const
225 int hlen
= (histLengths
[bank
] > pathHistBits
) ? pathHistBits
:
227 const unsigned int shiftedPc
= pc
>> instShiftAmt
;
230 (shiftedPc
>> ((int) abs(logTagTableSizes
[bank
] - bank
) + 1)) ^
231 threadHistory
[tid
].computeIndices
[bank
].comp
^
232 F(threadHistory
[tid
].pathHist
, hlen
, bank
);
234 return (index
& ((ULL(1) << (logTagTableSizes
[bank
])) - 1));
240 TAGEBase::gtag(ThreadID tid
, Addr pc
, int bank
) const
242 int tag
= (pc
>> instShiftAmt
) ^
243 threadHistory
[tid
].computeTags
[0][bank
].comp
^
244 (threadHistory
[tid
].computeTags
[1][bank
].comp
<< 1);
246 return (tag
& ((ULL(1) << tagTableTagWidths
[bank
]) - 1));
250 // Up-down saturating counter
253 TAGEBase::ctrUpdate(T
& ctr
, bool taken
, int nbits
)
255 assert(nbits
<= sizeof(T
) << 3);
257 if (ctr
< ((1 << (nbits
- 1)) - 1))
260 if (ctr
> -(1 << (nbits
- 1)))
265 // int8_t and int versions of this function may be needed
266 template void TAGEBase::ctrUpdate(int8_t & ctr
, bool taken
, int nbits
);
267 template void TAGEBase::ctrUpdate(int & ctr
, bool taken
, int nbits
);
269 // Up-down unsigned saturating counter
271 TAGEBase::unsignedCtrUpdate(uint8_t & ctr
, bool up
, unsigned nbits
)
273 assert(nbits
<= sizeof(uint8_t) << 3);
275 if (ctr
< ((1 << nbits
) - 1))
283 // Bimodal prediction
285 TAGEBase::getBimodePred(Addr pc
, BranchInfo
* bi
) const
287 return btablePrediction
[bi
->bimodalIndex
];
291 // Update the bimodal predictor: a hysteresis bit is shared among N prediction
292 // bits (N = 2 ^ logRatioBiModalHystEntries)
294 TAGEBase::baseUpdate(Addr pc
, bool taken
, BranchInfo
* bi
)
296 int inter
= (btablePrediction
[bi
->bimodalIndex
] << 1)
297 + btableHysteresis
[bi
->bimodalIndex
>> logRatioBiModalHystEntries
];
301 } else if (inter
> 0) {
304 const bool pred
= inter
>> 1;
305 const bool hyst
= inter
& 1;
306 btablePrediction
[bi
->bimodalIndex
] = pred
;
307 btableHysteresis
[bi
->bimodalIndex
>> logRatioBiModalHystEntries
] = hyst
;
308 DPRINTF(Tage
, "Updating branch %lx, pred:%d, hyst:%d\n", pc
, pred
, hyst
);
311 // shifting the global history: we manage the history in a big table in order
312 // to reduce simulation time
314 TAGEBase::updateGHist(uint8_t * &h
, bool dir
, uint8_t * tab
, int &pt
)
317 DPRINTF(Tage
, "Rolling over the histories\n");
318 // Copy beginning of globalHistoryBuffer to end, such that
319 // the last maxHist outcomes are still reachable
320 // through pt[0 .. maxHist - 1].
321 for (int i
= 0; i
< maxHist
; i
++)
322 tab
[histBufferSize
- maxHist
+ i
] = tab
[i
];
323 pt
= histBufferSize
- maxHist
;
328 h
[0] = (dir
) ? 1 : 0;
332 TAGEBase::calculateIndicesAndTags(ThreadID tid
, Addr branch_pc
,
335 // computes the table addresses and the partial tags
336 for (int i
= 1; i
<= nHistoryTables
; i
++) {
337 tableIndices
[i
] = gindex(tid
, branch_pc
, i
);
338 bi
->tableIndices
[i
] = tableIndices
[i
];
339 tableTags
[i
] = gtag(tid
, branch_pc
, i
);
340 bi
->tableTags
[i
] = tableTags
[i
];
345 TAGEBase::getUseAltIdx(BranchInfo
* bi
, Addr branch_pc
)
347 // There is only 1 counter on the base TAGE implementation
352 TAGEBase::tagePredict(ThreadID tid
, Addr branch_pc
,
353 bool cond_branch
, BranchInfo
* bi
)
356 bool pred_taken
= true;
361 calculateIndicesAndTags(tid
, pc
, bi
);
363 bi
->bimodalIndex
= bindex(pc
);
367 //Look for the bank with longest matching history
368 for (int i
= nHistoryTables
; i
> 0; i
--) {
370 gtable
[i
][tableIndices
[i
]].tag
== tableTags
[i
]) {
372 bi
->hitBankIndex
= tableIndices
[bi
->hitBank
];
376 //Look for the alternate bank
377 for (int i
= bi
->hitBank
- 1; i
> 0; i
--) {
379 gtable
[i
][tableIndices
[i
]].tag
== tableTags
[i
]) {
381 bi
->altBankIndex
= tableIndices
[bi
->altBank
];
385 //computes the prediction and the alternate prediction
386 if (bi
->hitBank
> 0) {
387 if (bi
->altBank
> 0) {
389 gtable
[bi
->altBank
][tableIndices
[bi
->altBank
]].ctr
>= 0;
392 bi
->altTaken
= getBimodePred(pc
, bi
);
395 bi
->longestMatchPred
=
396 gtable
[bi
->hitBank
][tableIndices
[bi
->hitBank
]].ctr
>= 0;
398 abs(2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) <= 1;
400 //if the entry is recognized as a newly allocated entry and
401 //useAltPredForNewlyAllocated is positive use the alternate
403 if ((useAltPredForNewlyAllocated
[getUseAltIdx(bi
, branch_pc
)] < 0)
404 || ! bi
->pseudoNewAlloc
) {
405 bi
->tagePred
= bi
->longestMatchPred
;
406 bi
->provider
= TAGE_LONGEST_MATCH
;
408 bi
->tagePred
= bi
->altTaken
;
409 bi
->provider
= bi
->altBank
? TAGE_ALT_MATCH
413 bi
->altTaken
= getBimodePred(pc
, bi
);
414 bi
->tagePred
= bi
->altTaken
;
415 bi
->longestMatchPred
= bi
->altTaken
;
416 bi
->provider
= BIMODAL_ONLY
;
418 //end TAGE prediction
420 pred_taken
= (bi
->tagePred
);
421 DPRINTF(Tage
, "Predict for %lx: taken?:%d, tagePred:%d, altPred:%d\n",
422 branch_pc
, pred_taken
, bi
->tagePred
, bi
->altTaken
);
424 bi
->branchPC
= branch_pc
;
425 bi
->condBranch
= cond_branch
;
430 TAGEBase::adjustAlloc(bool & alloc
, bool taken
, bool pred_taken
)
432 // Nothing for this base class implementation
436 TAGEBase::handleAllocAndUReset(bool alloc
, bool taken
, BranchInfo
* bi
,
440 // is there some "unuseful" entry to allocate
442 for (int i
= nHistoryTables
; i
> bi
->hitBank
; i
--) {
443 if (gtable
[i
][bi
->tableIndices
[i
]].u
< min
) {
444 min
= gtable
[i
][bi
->tableIndices
[i
]].u
;
448 // we allocate an entry with a longer history
449 // to avoid ping-pong, we do not choose systematically the next
450 // entry, but among the 3 next entries
452 ((ULL(1) << (nHistoryTables
- bi
->hitBank
- 1)) - 1);
453 int X
= bi
->hitBank
+ 1;
459 // No entry available, forces one to be available
461 gtable
[X
][bi
->tableIndices
[X
]].u
= 0;
466 unsigned numAllocated
= 0;
467 for (int i
= X
; i
<= nHistoryTables
; i
++) {
468 if ((gtable
[i
][bi
->tableIndices
[i
]].u
== 0)) {
469 gtable
[i
][bi
->tableIndices
[i
]].tag
= bi
->tableTags
[i
];
470 gtable
[i
][bi
->tableIndices
[i
]].ctr
= (taken
) ? 0 : -1;
472 if (numAllocated
== maxNumAlloc
) {
485 TAGEBase::handleUReset()
487 //periodic reset of u: reset is not complete but bit by bit
488 if ((tCounter
& ((ULL(1) << logUResetPeriod
) - 1)) == 0) {
489 // reset least significant bit
490 // most significant bit becomes least significant bit
491 for (int i
= 1; i
<= nHistoryTables
; i
++) {
492 for (int j
= 0; j
< (ULL(1) << logTagTableSizes
[i
]); j
++) {
493 resetUctr(gtable
[i
][j
].u
);
500 TAGEBase::resetUctr(uint8_t & u
)
506 TAGEBase::condBranchUpdate(ThreadID tid
, Addr branch_pc
, bool taken
,
507 BranchInfo
* bi
, int nrand
, Addr corrTarget
, bool pred
, bool preAdjustAlloc
)
510 // try to allocate a new entries only if prediction was wrong
511 bool alloc
= (bi
->tagePred
!= taken
) && (bi
->hitBank
< nHistoryTables
);
513 if (preAdjustAlloc
) {
514 adjustAlloc(alloc
, taken
, pred
);
517 if (bi
->hitBank
> 0) {
518 // Manage the selection between longest matching and alternate
519 // matching for "pseudo"-newly allocated longest matching entry
520 bool PseudoNewAlloc
= bi
->pseudoNewAlloc
;
521 // an entry is considered as newly allocated if its prediction
523 if (PseudoNewAlloc
) {
524 if (bi
->longestMatchPred
== taken
) {
527 // if it was delivering the correct prediction, no need to
528 // allocate new entry even if the overall prediction was false
529 if (bi
->longestMatchPred
!= bi
->altTaken
) {
531 useAltPredForNewlyAllocated
[getUseAltIdx(bi
, branch_pc
)],
532 bi
->altTaken
== taken
, useAltOnNaBits
);
537 if (!preAdjustAlloc
) {
538 adjustAlloc(alloc
, taken
, pred
);
541 handleAllocAndUReset(alloc
, taken
, bi
, nrand
);
543 handleTAGEUpdate(branch_pc
, taken
, bi
);
547 TAGEBase::handleTAGEUpdate(Addr branch_pc
, bool taken
, BranchInfo
* bi
)
549 if (bi
->hitBank
> 0) {
550 DPRINTF(Tage
, "Updating tag table entry (%d,%d) for branch %lx\n",
551 bi
->hitBank
, bi
->hitBankIndex
, branch_pc
);
552 ctrUpdate(gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
, taken
,
553 tagTableCounterBits
);
554 // if the provider entry is not certified to be useful also update
555 // the alternate prediction
556 if (gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
== 0) {
557 if (bi
->altBank
> 0) {
558 ctrUpdate(gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
, taken
,
559 tagTableCounterBits
);
560 DPRINTF(Tage
, "Updating tag table entry (%d,%d) for"
561 " branch %lx\n", bi
->hitBank
, bi
->hitBankIndex
,
564 if (bi
->altBank
== 0) {
565 baseUpdate(branch_pc
, taken
, bi
);
569 // update the u counter
570 if (bi
->tagePred
!= bi
->altTaken
) {
571 unsignedCtrUpdate(gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
,
572 bi
->tagePred
== taken
, tagTableUBits
);
575 baseUpdate(branch_pc
, taken
, bi
);
580 TAGEBase::updateHistories(ThreadID tid
, Addr branch_pc
, bool taken
,
581 BranchInfo
* bi
, bool speculative
,
582 const StaticInstPtr
&inst
, Addr target
)
584 if (speculative
!= speculativeHistUpdate
) {
587 ThreadHistory
& tHist
= threadHistory
[tid
];
589 bool pathbit
= ((branch_pc
>> instShiftAmt
) & 1);
590 //on a squash, return pointers to this and recompute indices.
591 //update user history
592 updateGHist(tHist
.gHist
, taken
, tHist
.globalHistory
, tHist
.ptGhist
);
593 tHist
.pathHist
= (tHist
.pathHist
<< 1) + pathbit
;
594 tHist
.pathHist
= (tHist
.pathHist
& ((ULL(1) << pathHistBits
) - 1));
597 bi
->ptGhist
= tHist
.ptGhist
;
598 bi
->pathHist
= tHist
.pathHist
;
601 //prepare next index and tag computations for user branchs
602 for (int i
= 1; i
<= nHistoryTables
; i
++)
605 bi
->ci
[i
] = tHist
.computeIndices
[i
].comp
;
606 bi
->ct0
[i
] = tHist
.computeTags
[0][i
].comp
;
607 bi
->ct1
[i
] = tHist
.computeTags
[1][i
].comp
;
609 tHist
.computeIndices
[i
].update(tHist
.gHist
);
610 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
611 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
613 DPRINTF(Tage
, "Updating global histories with branch:%lx; taken?:%d, "
614 "path Hist: %x; pointer:%d\n", branch_pc
, taken
, tHist
.pathHist
,
616 assert(threadHistory
[tid
].gHist
==
617 &threadHistory
[tid
].globalHistory
[threadHistory
[tid
].ptGhist
]);
621 TAGEBase::squash(ThreadID tid
, bool taken
, TAGEBase::BranchInfo
*bi
,
624 if (!speculativeHistUpdate
) {
625 /* If there are no speculative updates, no actions are needed */
629 ThreadHistory
& tHist
= threadHistory
[tid
];
630 DPRINTF(Tage
, "Restoring branch info: %lx; taken? %d; PathHistory:%x, "
631 "pointer:%d\n", bi
->branchPC
,taken
, bi
->pathHist
, bi
->ptGhist
);
632 tHist
.pathHist
= bi
->pathHist
;
633 tHist
.ptGhist
= bi
->ptGhist
;
634 tHist
.gHist
= &(tHist
.globalHistory
[tHist
.ptGhist
]);
635 tHist
.gHist
[0] = (taken
? 1 : 0);
636 for (int i
= 1; i
<= nHistoryTables
; i
++) {
637 tHist
.computeIndices
[i
].comp
= bi
->ci
[i
];
638 tHist
.computeTags
[0][i
].comp
= bi
->ct0
[i
];
639 tHist
.computeTags
[1][i
].comp
= bi
->ct1
[i
];
640 tHist
.computeIndices
[i
].update(tHist
.gHist
);
641 tHist
.computeTags
[0][i
].update(tHist
.gHist
);
642 tHist
.computeTags
[1][i
].update(tHist
.gHist
);
647 TAGEBase::extraAltCalc(BranchInfo
* bi
)
649 // do nothing. This is only used in some derived classes
654 TAGEBase::updateStats(bool taken
, BranchInfo
* bi
)
656 if (taken
== bi
->tagePred
) {
657 // correct prediction
658 switch (bi
->provider
) {
659 case BIMODAL_ONLY
: tageBimodalProviderCorrect
++; break;
660 case TAGE_LONGEST_MATCH
: tageLongestMatchProviderCorrect
++; break;
661 case BIMODAL_ALT_MATCH
: bimodalAltMatchProviderCorrect
++; break;
662 case TAGE_ALT_MATCH
: tageAltMatchProviderCorrect
++; break;
666 switch (bi
->provider
) {
667 case BIMODAL_ONLY
: tageBimodalProviderWrong
++; break;
668 case TAGE_LONGEST_MATCH
:
669 tageLongestMatchProviderWrong
++;
670 if (bi
->altTaken
== taken
) {
671 tageAltMatchProviderWouldHaveHit
++;
674 case BIMODAL_ALT_MATCH
:
675 bimodalAltMatchProviderWrong
++;
678 tageAltMatchProviderWrong
++;
682 switch (bi
->provider
) {
683 case BIMODAL_ALT_MATCH
:
685 if (bi
->longestMatchPred
== taken
) {
686 tageLongestMatchProviderWouldHaveHit
++;
691 switch (bi
->provider
) {
692 case TAGE_LONGEST_MATCH
:
694 tageLongestMatchProvider
[bi
->hitBank
]++;
695 tageAltMatchProvider
[bi
->altBank
]++;
701 TAGEBase::getGHR(ThreadID tid
, BranchInfo
*bi
) const
704 for (unsigned i
= 0; i
< 32; i
++) {
705 // Make sure we don't go out of bounds
706 int gh_offset
= bi
->ptGhist
+ i
;
707 assert(&(threadHistory
[tid
].globalHistory
[gh_offset
]) <
708 threadHistory
[tid
].globalHistory
+ histBufferSize
);
709 val
|= ((threadHistory
[tid
].globalHistory
[gh_offset
] & 0x1) << i
);
718 tageLongestMatchProviderCorrect
719 .name(name() + ".tageLongestMatchProviderCorrect")
720 .desc("Number of times TAGE Longest Match is the provider and "
721 "the prediction is correct");
723 tageAltMatchProviderCorrect
724 .name(name() + ".tageAltMatchProviderCorrect")
725 .desc("Number of times TAGE Alt Match is the provider and "
726 "the prediction is correct");
728 bimodalAltMatchProviderCorrect
729 .name(name() + ".bimodalAltMatchProviderCorrect")
730 .desc("Number of times TAGE Alt Match is the bimodal and it is the "
731 "provider and the prediction is correct");
733 tageBimodalProviderCorrect
734 .name(name() + ".tageBimodalProviderCorrect")
735 .desc("Number of times there are no hits on the TAGE tables "
736 "and the bimodal prediction is correct");
738 tageLongestMatchProviderWrong
739 .name(name() + ".tageLongestMatchProviderWrong")
740 .desc("Number of times TAGE Longest Match is the provider and "
741 "the prediction is wrong");
743 tageAltMatchProviderWrong
744 .name(name() + ".tageAltMatchProviderWrong")
745 .desc("Number of times TAGE Alt Match is the provider and "
746 "the prediction is wrong");
748 bimodalAltMatchProviderWrong
749 .name(name() + ".bimodalAltMatchProviderWrong")
750 .desc("Number of times TAGE Alt Match is the bimodal and it is the "
751 "provider and the prediction is wrong");
753 tageBimodalProviderWrong
754 .name(name() + ".tageBimodalProviderWrong")
755 .desc("Number of times there are no hits on the TAGE tables "
756 "and the bimodal prediction is wrong");
758 tageAltMatchProviderWouldHaveHit
759 .name(name() + ".tageAltMatchProviderWouldHaveHit")
760 .desc("Number of times TAGE Longest Match is the provider, "
761 "the prediction is wrong and Alt Match prediction was correct");
763 tageLongestMatchProviderWouldHaveHit
764 .name(name() + ".tageLongestMatchProviderWouldHaveHit")
765 .desc("Number of times TAGE Alt Match is the provider, the "
766 "prediction is wrong and Longest Match prediction was correct");
768 tageLongestMatchProvider
769 .init(nHistoryTables
+ 1)
770 .name(name() + ".tageLongestMatchProvider")
771 .desc("TAGE provider for longest match");
774 .init(nHistoryTables
+ 1)
775 .name(name() + ".tageAltMatchProvider")
776 .desc("TAGE provider for alt match");
780 TAGEBase::getCtr(int hitBank
, int hitBankIndex
) const
782 return gtable
[hitBank
][hitBankIndex
].ctr
;
786 TAGEBase::getTageCtrBits() const
788 return tagTableCounterBits
;
792 TAGEBase::getPathHist(ThreadID tid
) const
794 return threadHistory
[tid
].pathHist
;
798 TAGEBase::isSpeculativeUpdateEnabled() const
800 return speculativeHistUpdate
;
804 TAGEBase::getSizeInBits() const {
806 for (int i
= 1; i
<= nHistoryTables
; i
++) {
807 bits
+= (1 << logTagTableSizes
[i
]) *
808 (tagTableCounterBits
+ tagTableUBits
+ tagTableTagWidths
[i
]);
810 uint64_t bimodalTableSize
= ULL(1) << logTagTableSizes
[0];
811 bits
+= numUseAltOnNa
* useAltOnNaBits
;
812 bits
+= bimodalTableSize
;
813 bits
+= (bimodalTableSize
>> logRatioBiModalHystEntries
);
814 bits
+= histLengths
[nHistoryTables
];
815 bits
+= pathHistBits
;
816 bits
+= logUResetPeriod
;
821 TAGEBaseParams::create()
823 return new TAGEBase(this);