tage.cc (13455:56e25a5f9603) | tage.cc (13626:d6a6358aa6db) |
---|---|
1/* 2 * Copyright (c) 2014 The University of Wisconsin 3 * 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) 7 * 8 * All rights reserved. --- 33 unchanged lines hidden (view full) --- 42 43#include "base/intmath.hh" 44#include "base/logging.hh" 45#include "base/random.hh" 46#include "base/trace.hh" 47#include "debug/Fetch.hh" 48#include "debug/Tage.hh" 49 | 1/* 2 * Copyright (c) 2014 The University of Wisconsin 3 * 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) 7 * 8 * All rights reserved. --- 33 unchanged lines hidden (view full) --- 42 43#include "base/intmath.hh" 44#include "base/logging.hh" 45#include "base/random.hh" 46#include "base/trace.hh" 47#include "debug/Fetch.hh" 48#include "debug/Tage.hh" 49 |
50TAGE::TAGE(const TAGEParams *params) 51 : BPredUnit(params), 52 logRatioBiModalHystEntries(params->logRatioBiModalHystEntries), 53 nHistoryTables(params->nHistoryTables), 54 tagTableCounterBits(params->tagTableCounterBits), 55 tagTableUBits(params->tagTableUBits), 56 histBufferSize(params->histBufferSize), 57 minHist(params->minHist), 58 maxHist(params->maxHist), 59 pathHistBits(params->pathHistBits), 60 tagTableTagWidths(params->tagTableTagWidths), 61 logTagTableSizes(params->logTagTableSizes), 62 threadHistory(params->numThreads), 63 logUResetPeriod(params->logUResetPeriod), 64 useAltOnNaBits(params->useAltOnNaBits) | 50TAGE::TAGE(const TAGEParams *params) : BPredUnit(params), tage(params->tage) |
65{ | 51{ |
66 // Current method for periodically resetting the u counter bits only 67 // works for 1 or 2 bits 68 // Also make sure that it is not 0 69 assert(tagTableUBits <= 2 && (tagTableUBits > 0)); 70 71 // we use int type for the path history, so it cannot be more than 72 // its size 73 assert(pathHistBits <= (sizeof(int)*8)); 74 75 // initialize the counter to half of the period 76 assert(logUResetPeriod != 0); 77 tCounter = ULL(1) << (logUResetPeriod - 1); 78 79 assert(params->histBufferSize > params->maxHist * 2); 80 useAltPredForNewlyAllocated = 0; 81 82 for (auto& history : threadHistory) { 83 history.pathHist = 0; 84 history.globalHistory = new uint8_t[histBufferSize]; 85 history.gHist = history.globalHistory; 86 memset(history.gHist, 0, histBufferSize); 87 history.ptGhist = 0; 88 } 89 90 histLengths = new int [nHistoryTables+1]; 91 histLengths[1] = minHist; 92 histLengths[nHistoryTables] = maxHist; 93 94 for (int i = 2; i <= nHistoryTables; i++) { 95 histLengths[i] = (int) (((double) minHist * 96 pow ((double) (maxHist) / (double) minHist, 97 (double) (i - 1) / (double) ((nHistoryTables- 1)))) 98 + 0.5); 99 } 100 101 assert(tagTableTagWidths.size() == (nHistoryTables+1)); 102 assert(logTagTableSizes.size() == (nHistoryTables+1)); 103 104 // First entry is for the Bimodal table and it is untagged in this 105 // implementation 106 assert(tagTableTagWidths[0] == 0); 107 108 for (auto& history : threadHistory) { 109 history.computeIndices = new FoldedHistory[nHistoryTables+1]; 110 history.computeTags[0] = new FoldedHistory[nHistoryTables+1]; 111 history.computeTags[1] = new FoldedHistory[nHistoryTables+1]; 112 113 for (int i = 1; i <= nHistoryTables; i++) { 114 history.computeIndices[i].init( 115 histLengths[i], (logTagTableSizes[i])); 116 history.computeTags[0][i].init( 117 history.computeIndices[i].origLength, tagTableTagWidths[i]); 118 history.computeTags[1][i].init( 119 history.computeIndices[i].origLength, tagTableTagWidths[i]-1); 120 DPRINTF(Tage, "HistLength:%d, TTSize:%d, TTTWidth:%d\n", 121 histLengths[i], logTagTableSizes[i], tagTableTagWidths[i]); 122 } 123 } 124 125 const uint64_t bimodalTableSize = ULL(1) << logTagTableSizes[0]; 126 btablePrediction.resize(bimodalTableSize, false); 127 btableHysteresis.resize(bimodalTableSize >> logRatioBiModalHystEntries, 128 true); 129 130 gtable = new TageEntry*[nHistoryTables + 1]; 131 for (int i = 1; i <= nHistoryTables; i++) { 132 gtable[i] = new TageEntry[1<<(logTagTableSizes[i])]; 133 } 134 135 tableIndices = new int [nHistoryTables+1]; 136 tableTags = new int [nHistoryTables+1]; | |
137} 138 | 52} 53 |
139int 140TAGE::bindex(Addr pc_in) const 141{ 142 return ((pc_in >> instShiftAmt) & ((ULL(1) << (logTagTableSizes[0])) - 1)); 143} 144 145int 146TAGE::F(int A, int size, int bank) const 147{ 148 int A1, A2; 149 150 A = A & ((ULL(1) << size) - 1); 151 A1 = (A & ((ULL(1) << logTagTableSizes[bank]) - 1)); 152 A2 = (A >> logTagTableSizes[bank]); 153 A2 = ((A2 << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1)) 154 + (A2 >> (logTagTableSizes[bank] - bank)); 155 A = A1 ^ A2; 156 A = ((A << bank) & ((ULL(1) << logTagTableSizes[bank]) - 1)) 157 + (A >> (logTagTableSizes[bank] - bank)); 158 return (A); 159} 160 161 162// gindex computes a full hash of pc, ghist and pathHist 163int 164TAGE::gindex(ThreadID tid, Addr pc, int bank) const 165{ 166 int index; 167 int hlen = (histLengths[bank] > pathHistBits) ? pathHistBits : 168 histLengths[bank]; 169 const Addr shiftedPc = pc >> instShiftAmt; 170 index = 171 shiftedPc ^ 172 (shiftedPc >> ((int) abs(logTagTableSizes[bank] - bank) + 1)) ^ 173 threadHistory[tid].computeIndices[bank].comp ^ 174 F(threadHistory[tid].pathHist, hlen, bank); 175 176 return (index & ((ULL(1) << (logTagTableSizes[bank])) - 1)); 177} 178 179 180// Tag computation 181uint16_t 182TAGE::gtag(ThreadID tid, Addr pc, int bank) const 183{ 184 int tag = (pc >> instShiftAmt) ^ 185 threadHistory[tid].computeTags[0][bank].comp ^ 186 (threadHistory[tid].computeTags[1][bank].comp << 1); 187 188 return (tag & ((ULL(1) << tagTableTagWidths[bank]) - 1)); 189} 190 191 192// Up-down saturating counter 193void 194TAGE::ctrUpdate(int8_t & ctr, bool taken, int nbits) 195{ 196 assert(nbits <= sizeof(int8_t) << 3); 197 if (taken) { 198 if (ctr < ((1 << (nbits - 1)) - 1)) 199 ctr++; 200 } else { 201 if (ctr > -(1 << (nbits - 1))) 202 ctr--; 203 } 204} 205 206// Up-down unsigned saturating counter 207void 208TAGE::unsignedCtrUpdate(uint8_t & ctr, bool up, unsigned nbits) 209{ 210 assert(nbits <= sizeof(uint8_t) << 3); 211 if (up) { 212 if (ctr < ((1 << nbits) - 1)) 213 ctr++; 214 } else { 215 if (ctr) 216 ctr--; 217 } 218} 219 220// Bimodal prediction 221bool 222TAGE::getBimodePred(Addr pc, TageBranchInfo* bi) const 223{ 224 return btablePrediction[bi->bimodalIndex]; 225} 226 227 228// Update the bimodal predictor: a hysteresis bit is shared among N prediction 229// bits (N = 2 ^ logRatioBiModalHystEntries) 230void 231TAGE::baseUpdate(Addr pc, bool taken, TageBranchInfo* bi) 232{ 233 int inter = (btablePrediction[bi->bimodalIndex] << 1) 234 + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries]; 235 if (taken) { 236 if (inter < 3) 237 inter++; 238 } else if (inter > 0) { 239 inter--; 240 } 241 const bool pred = inter >> 1; 242 const bool hyst = inter & 1; 243 btablePrediction[bi->bimodalIndex] = pred; 244 btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries] = hyst; 245 DPRINTF(Tage, "Updating branch %lx, pred:%d, hyst:%d\n", pc, pred, hyst); 246} 247 248// shifting the global history: we manage the history in a big table in order 249// to reduce simulation time 250void 251TAGE::updateGHist(uint8_t * &h, bool dir, uint8_t * tab, int &pt) 252{ 253 if (pt == 0) { 254 DPRINTF(Tage, "Rolling over the histories\n"); 255 // Copy beginning of globalHistoryBuffer to end, such that 256 // the last maxHist outcomes are still reachable 257 // through pt[0 .. maxHist - 1]. 258 for (int i = 0; i < maxHist; i++) 259 tab[histBufferSize - maxHist + i] = tab[i]; 260 pt = histBufferSize - maxHist; 261 h = &tab[pt]; 262 } 263 pt--; 264 h--; 265 h[0] = (dir) ? 1 : 0; 266} 267 | |
268// Get GHR for hashing indirect predictor 269// Build history backwards from pointer in 270// bp_history. 271unsigned 272TAGE::getGHR(ThreadID tid, void *bp_history) const 273{ 274 TageBranchInfo* bi = static_cast<TageBranchInfo*>(bp_history); | 54// Get GHR for hashing indirect predictor 55// Build history backwards from pointer in 56// bp_history. 57unsigned 58TAGE::getGHR(ThreadID tid, void *bp_history) const 59{ 60 TageBranchInfo* bi = static_cast<TageBranchInfo*>(bp_history); |
275 unsigned val = 0; 276 for (unsigned i = 0; i < 32; i++) { 277 // Make sure we don't go out of bounds 278 int gh_offset = bi->ptGhist + i; 279 assert(&(threadHistory[tid].globalHistory[gh_offset]) < 280 threadHistory[tid].globalHistory + histBufferSize); 281 val |= ((threadHistory[tid].globalHistory[gh_offset] & 0x1) << i); 282 } 283 284 return val; | 61 return tage->getGHR(tid, bi->tageBranchInfo); |
285} 286 | 62} 63 |
287//prediction 288bool 289TAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b) 290{ 291 TageBranchInfo *bi = new TageBranchInfo(nHistoryTables+1); 292 b = (void*)(bi); 293 return tagePredict(tid, branch_pc, cond_branch, bi); 294} 295 296bool 297TAGE::tagePredict(ThreadID tid, Addr branch_pc, 298 bool cond_branch, TageBranchInfo* bi) 299{ 300 Addr pc = branch_pc; 301 bool pred_taken = true; 302 303 if (cond_branch) { 304 // TAGE prediction 305 306 // computes the table addresses and the partial tags 307 for (int i = 1; i <= nHistoryTables; i++) { 308 tableIndices[i] = gindex(tid, pc, i); 309 bi->tableIndices[i] = tableIndices[i]; 310 tableTags[i] = gtag(tid, pc, i); 311 bi->tableTags[i] = tableTags[i]; 312 } 313 314 bi->bimodalIndex = bindex(pc); 315 316 bi->hitBank = 0; 317 bi->altBank = 0; 318 //Look for the bank with longest matching history 319 for (int i = nHistoryTables; i > 0; i--) { 320 if (gtable[i][tableIndices[i]].tag == tableTags[i]) { 321 bi->hitBank = i; 322 bi->hitBankIndex = tableIndices[bi->hitBank]; 323 break; 324 } 325 } 326 //Look for the alternate bank 327 for (int i = bi->hitBank - 1; i > 0; i--) { 328 if (gtable[i][tableIndices[i]].tag == tableTags[i]) { 329 bi->altBank = i; 330 bi->altBankIndex = tableIndices[bi->altBank]; 331 break; 332 } 333 } 334 //computes the prediction and the alternate prediction 335 if (bi->hitBank > 0) { 336 if (bi->altBank > 0) { 337 bi->altTaken = 338 gtable[bi->altBank][tableIndices[bi->altBank]].ctr >= 0; 339 }else { 340 bi->altTaken = getBimodePred(pc, bi); 341 } 342 343 bi->longestMatchPred = 344 gtable[bi->hitBank][tableIndices[bi->hitBank]].ctr >= 0; 345 bi->pseudoNewAlloc = 346 abs(2 * gtable[bi->hitBank][bi->hitBankIndex].ctr + 1) <= 1; 347 348 //if the entry is recognized as a newly allocated entry and 349 //useAltPredForNewlyAllocated is positive use the alternate 350 //prediction 351 if ((useAltPredForNewlyAllocated < 0) || ! bi->pseudoNewAlloc) { 352 bi->tagePred = bi->longestMatchPred; 353 bi->provider = TAGE_LONGEST_MATCH; 354 } else { 355 bi->tagePred = bi->altTaken; 356 bi->provider = bi->altBank ? TAGE_ALT_MATCH 357 : BIMODAL_ALT_MATCH; 358 } 359 } else { 360 bi->altTaken = getBimodePred(pc, bi); 361 bi->tagePred = bi->altTaken; 362 bi->longestMatchPred = bi->altTaken; 363 bi->provider = BIMODAL_ONLY; 364 } 365 //end TAGE prediction 366 367 pred_taken = (bi->tagePred); 368 DPRINTF(Tage, "Predict for %lx: taken?:%d, tagePred:%d, altPred:%d\n", 369 branch_pc, pred_taken, bi->tagePred, bi->altTaken); 370 } 371 bi->branchPC = branch_pc; 372 bi->condBranch = cond_branch; 373 return pred_taken; 374} 375 | |
376// PREDICTOR UPDATE 377void 378TAGE::update(ThreadID tid, Addr branch_pc, bool taken, void* bp_history, | 64// PREDICTOR UPDATE 65void 66TAGE::update(ThreadID tid, Addr branch_pc, bool taken, void* bp_history, |
379 bool squashed) | 67 bool squashed, const StaticInstPtr & inst, Addr corrTarget) |
380{ 381 assert(bp_history); 382 383 TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history); 384 | 68{ 69 assert(bp_history); 70 71 TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history); 72 |
73 assert(corrTarget != MaxAddr); 74 |
|
385 if (squashed) { 386 // This restores the global history, then update it 387 // and recomputes the folded histories. | 75 if (squashed) { 76 // This restores the global history, then update it 77 // and recomputes the folded histories. |
388 squash(tid, taken, bp_history); | 78 tage->squash(tid, taken, bi->tageBranchInfo, corrTarget); |
389 return; 390 } 391 | 79 return; 80 } 81 |
392 int nrand = random_mt.random<int>(0,3); 393 if (bi->condBranch) { | 82 int nrand = TAGEBase::getRandom() & 3; 83 if (bi->tageBranchInfo->condBranch) { |
394 DPRINTF(Tage, "Updating tables for branch:%lx; taken?:%d\n", 395 branch_pc, taken); | 84 DPRINTF(Tage, "Updating tables for branch:%lx; taken?:%d\n", 85 branch_pc, taken); |
396 updateStats(taken, bi); 397 condBranchUpdate(branch_pc, taken, bi, nrand); | 86 tage->updateStats(taken, bi->tageBranchInfo); 87 tage->condBranchUpdate(tid, branch_pc, taken, bi->tageBranchInfo, 88 nrand, corrTarget); |
398 } | 89 } |
399 if (!squashed) { 400 delete bi; 401 } 402} | |
403 | 90 |
404void 405TAGE::condBranchUpdate(Addr branch_pc, bool taken, 406 TageBranchInfo* bi, int nrand) 407{ 408 // TAGE UPDATE 409 // try to allocate a new entries only if prediction was wrong 410 bool longest_match_pred = false; 411 bool alloc = (bi->tagePred != taken) && (bi->hitBank < nHistoryTables); 412 if (bi->hitBank > 0) { 413 // Manage the selection between longest matching and alternate 414 // matching for "pseudo"-newly allocated longest matching entry 415 longest_match_pred = bi->longestMatchPred; 416 bool PseudoNewAlloc = bi->pseudoNewAlloc; 417 // an entry is considered as newly allocated if its prediction 418 // counter is weak 419 if (PseudoNewAlloc) { 420 if (longest_match_pred == taken) { 421 alloc = false; 422 } 423 // if it was delivering the correct prediction, no need to 424 // allocate new entry even if the overall prediction was false 425 if (longest_match_pred != bi->altTaken) { 426 ctrUpdate(useAltPredForNewlyAllocated, 427 bi->altTaken == taken, useAltOnNaBits); 428 } 429 } 430 } | 91 tage->updateHistories(tid, branch_pc, taken, bi->tageBranchInfo, false, 92 inst, corrTarget); |
431 | 93 |
432 if (alloc) { 433 // is there some "unuseful" entry to allocate 434 uint8_t min = 1; 435 for (int i = nHistoryTables; i > bi->hitBank; i--) { 436 if (gtable[i][bi->tableIndices[i]].u < min) { 437 min = gtable[i][bi->tableIndices[i]].u; 438 } 439 } 440 441 // we allocate an entry with a longer history 442 // to avoid ping-pong, we do not choose systematically the next 443 // entry, but among the 3 next entries 444 int Y = nrand & 445 ((ULL(1) << (nHistoryTables - bi->hitBank - 1)) - 1); 446 int X = bi->hitBank + 1; 447 if (Y & 1) { 448 X++; 449 if (Y & 2) 450 X++; 451 } 452 // No entry available, forces one to be available 453 if (min > 0) { 454 gtable[X][bi->tableIndices[X]].u = 0; 455 } 456 457 458 //Allocate only one entry 459 for (int i = X; i <= nHistoryTables; i++) { 460 if ((gtable[i][bi->tableIndices[i]].u == 0)) { 461 gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i]; 462 gtable[i][bi->tableIndices[i]].ctr = (taken) ? 0 : -1; 463 break; 464 } 465 } 466 } 467 //periodic reset of u: reset is not complete but bit by bit 468 tCounter++; 469 if ((tCounter & ((ULL(1) << logUResetPeriod) - 1)) == 0) { 470 // reset least significant bit 471 // most significant bit becomes least significant bit 472 for (int i = 1; i <= nHistoryTables; i++) { 473 for (int j = 0; j < (ULL(1) << logTagTableSizes[i]); j++) { 474 gtable[i][j].u = gtable[i][j].u >> 1; 475 } 476 } 477 } 478 479 if (bi->hitBank > 0) { 480 DPRINTF(Tage, "Updating tag table entry (%d,%d) for branch %lx\n", 481 bi->hitBank, bi->hitBankIndex, branch_pc); 482 ctrUpdate(gtable[bi->hitBank][bi->hitBankIndex].ctr, taken, 483 tagTableCounterBits); 484 // if the provider entry is not certified to be useful also update 485 // the alternate prediction 486 if (gtable[bi->hitBank][bi->hitBankIndex].u == 0) { 487 if (bi->altBank > 0) { 488 ctrUpdate(gtable[bi->altBank][bi->altBankIndex].ctr, taken, 489 tagTableCounterBits); 490 DPRINTF(Tage, "Updating tag table entry (%d,%d) for" 491 " branch %lx\n", bi->hitBank, bi->hitBankIndex, 492 branch_pc); 493 } 494 if (bi->altBank == 0) { 495 baseUpdate(branch_pc, taken, bi); 496 } 497 } 498 499 // update the u counter 500 if (bi->tagePred != bi->altTaken) { 501 unsignedCtrUpdate(gtable[bi->hitBank][bi->hitBankIndex].u, 502 bi->tagePred == taken, tagTableUBits); 503 } 504 } else { 505 baseUpdate(branch_pc, taken, bi); 506 } | 94 delete bi; |
507} 508 509void | 95} 96 97void |
510TAGE::updateHistories(ThreadID tid, Addr branch_pc, bool taken, void* b) | 98TAGE::squash(ThreadID tid, void *bp_history) |
511{ | 99{ |
512 TageBranchInfo* bi = (TageBranchInfo*)(b); 513 ThreadHistory& tHist = threadHistory[tid]; 514 // UPDATE HISTORIES 515 bool pathbit = ((branch_pc >> instShiftAmt) & 1); 516 //on a squash, return pointers to this and recompute indices. 517 //update user history 518 updateGHist(tHist.gHist, taken, tHist.globalHistory, tHist.ptGhist); 519 tHist.pathHist = (tHist.pathHist << 1) + pathbit; 520 tHist.pathHist = (tHist.pathHist & ((ULL(1) << pathHistBits) - 1)); 521 522 bi->ptGhist = tHist.ptGhist; 523 bi->pathHist = tHist.pathHist; 524 //prepare next index and tag computations for user branchs 525 for (int i = 1; i <= nHistoryTables; i++) 526 { 527 bi->ci[i] = tHist.computeIndices[i].comp; 528 bi->ct0[i] = tHist.computeTags[0][i].comp; 529 bi->ct1[i] = tHist.computeTags[1][i].comp; 530 tHist.computeIndices[i].update(tHist.gHist); 531 tHist.computeTags[0][i].update(tHist.gHist); 532 tHist.computeTags[1][i].update(tHist.gHist); 533 } 534 DPRINTF(Tage, "Updating global histories with branch:%lx; taken?:%d, " 535 "path Hist: %x; pointer:%d\n", branch_pc, taken, tHist.pathHist, 536 tHist.ptGhist); | 100 TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history); 101 DPRINTF(Tage, "Deleting branch info: %lx\n", bi->tageBranchInfo->branchPC); 102 delete bi; |
537} 538 | 103} 104 |
539void 540TAGE::squash(ThreadID tid, bool taken, void *bp_history) | 105bool 106TAGE::predict(ThreadID tid, Addr branch_pc, bool cond_branch, void* &b) |
541{ | 107{ |
542 TageBranchInfo* bi = (TageBranchInfo*)(bp_history); 543 ThreadHistory& tHist = threadHistory[tid]; 544 DPRINTF(Tage, "Restoring branch info: %lx; taken? %d; PathHistory:%x, " 545 "pointer:%d\n", bi->branchPC,taken, bi->pathHist, bi->ptGhist); 546 tHist.pathHist = bi->pathHist; 547 tHist.ptGhist = bi->ptGhist; 548 tHist.gHist = &(tHist.globalHistory[tHist.ptGhist]); 549 tHist.gHist[0] = (taken ? 1 : 0); 550 for (int i = 1; i <= nHistoryTables; i++) { 551 tHist.computeIndices[i].comp = bi->ci[i]; 552 tHist.computeTags[0][i].comp = bi->ct0[i]; 553 tHist.computeTags[1][i].comp = bi->ct1[i]; 554 tHist.computeIndices[i].update(tHist.gHist); 555 tHist.computeTags[0][i].update(tHist.gHist); 556 tHist.computeTags[1][i].update(tHist.gHist); 557 } | 108 TageBranchInfo *bi = new TageBranchInfo(*tage); 109 b = (void*)(bi); 110 return tage->tagePredict(tid, branch_pc, cond_branch, bi->tageBranchInfo); |
558} 559 | 111} 112 |
560void 561TAGE::squash(ThreadID tid, void *bp_history) 562{ 563 TageBranchInfo* bi = (TageBranchInfo*)(bp_history); 564 DPRINTF(Tage, "Deleting branch info: %lx\n", bi->branchPC); 565 delete bi; 566} 567 | |
568bool 569TAGE::lookup(ThreadID tid, Addr branch_pc, void* &bp_history) 570{ 571 bool retval = predict(tid, branch_pc, true, bp_history); 572 | 113bool 114TAGE::lookup(ThreadID tid, Addr branch_pc, void* &bp_history) 115{ 116 bool retval = predict(tid, branch_pc, true, bp_history); 117 |
118 TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history); 119 |
|
573 DPRINTF(Tage, "Lookup branch: %lx; predict:%d\n", branch_pc, retval); | 120 DPRINTF(Tage, "Lookup branch: %lx; predict:%d\n", branch_pc, retval); |
574 updateHistories(tid, branch_pc, retval, bp_history); 575 assert(threadHistory[tid].gHist == 576 &threadHistory[tid].globalHistory[threadHistory[tid].ptGhist]); | |
577 | 121 |
122 tage->updateHistories(tid, branch_pc, retval, bi->tageBranchInfo, true); 123 |
|
578 return retval; 579} 580 581void 582TAGE::btbUpdate(ThreadID tid, Addr branch_pc, void* &bp_history) 583{ | 124 return retval; 125} 126 127void 128TAGE::btbUpdate(ThreadID tid, Addr branch_pc, void* &bp_history) 129{ |
584 TageBranchInfo* bi = (TageBranchInfo*) bp_history; 585 ThreadHistory& tHist = threadHistory[tid]; 586 DPRINTF(Tage, "BTB miss resets prediction: %lx\n", branch_pc); 587 assert(tHist.gHist == &tHist.globalHistory[tHist.ptGhist]); 588 tHist.gHist[0] = 0; 589 for (int i = 1; i <= nHistoryTables; i++) { 590 tHist.computeIndices[i].comp = bi->ci[i]; 591 tHist.computeTags[0][i].comp = bi->ct0[i]; 592 tHist.computeTags[1][i].comp = bi->ct1[i]; 593 tHist.computeIndices[i].update(tHist.gHist); 594 tHist.computeTags[0][i].update(tHist.gHist); 595 tHist.computeTags[1][i].update(tHist.gHist); 596 } | 130 TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history); 131 tage->btbUpdate(tid, branch_pc, bi->tageBranchInfo); |
597} 598 599void 600TAGE::uncondBranch(ThreadID tid, Addr br_pc, void* &bp_history) 601{ 602 DPRINTF(Tage, "UnConditionalBranch: %lx\n", br_pc); 603 predict(tid, br_pc, false, bp_history); | 132} 133 134void 135TAGE::uncondBranch(ThreadID tid, Addr br_pc, void* &bp_history) 136{ 137 DPRINTF(Tage, "UnConditionalBranch: %lx\n", br_pc); 138 predict(tid, br_pc, false, bp_history); |
604 updateHistories(tid, br_pc, true, bp_history); 605 assert(threadHistory[tid].gHist == 606 &threadHistory[tid].globalHistory[threadHistory[tid].ptGhist]); | 139 TageBranchInfo *bi = static_cast<TageBranchInfo*>(bp_history); 140 tage->updateHistories(tid, br_pc, true, bi->tageBranchInfo, true); |
607} 608 | 141} 142 |
609void 610TAGE::updateStats(bool taken, TageBranchInfo* bi) 611{ 612 if (taken == bi->tagePred) { 613 // correct prediction 614 switch (bi->provider) { 615 case BIMODAL_ONLY: tageBimodalProviderCorrect++; break; 616 case TAGE_LONGEST_MATCH: tageLongestMatchProviderCorrect++; break; 617 case BIMODAL_ALT_MATCH: bimodalAltMatchProviderCorrect++; break; 618 case TAGE_ALT_MATCH: tageAltMatchProviderCorrect++; break; 619 } 620 } else { 621 // wrong prediction 622 switch (bi->provider) { 623 case BIMODAL_ONLY: tageBimodalProviderWrong++; break; 624 case TAGE_LONGEST_MATCH: 625 tageLongestMatchProviderWrong++; 626 if (bi->altTaken == taken) { 627 tageAltMatchProviderWouldHaveHit++; 628 } 629 break; 630 case BIMODAL_ALT_MATCH: 631 bimodalAltMatchProviderWrong++; 632 break; 633 case TAGE_ALT_MATCH: 634 tageAltMatchProviderWrong++; 635 break; 636 } 637 638 switch (bi->provider) { 639 case BIMODAL_ALT_MATCH: 640 case TAGE_ALT_MATCH: 641 if (bi->longestMatchPred == taken) { 642 tageLongestMatchProviderWouldHaveHit++; 643 } 644 } 645 } 646 647 switch (bi->provider) { 648 case TAGE_LONGEST_MATCH: 649 case TAGE_ALT_MATCH: 650 tageLongestMatchProvider[bi->hitBank]++; 651 tageAltMatchProvider[bi->altBank]++; 652 break; 653 } 654} 655 656void 657TAGE::regStats() 658{ 659 BPredUnit::regStats(); 660 661 tageLongestMatchProviderCorrect 662 .name(name() + ".tageLongestMatchProviderCorrect") 663 .desc("Number of times TAGE Longest Match is the provider and " 664 "the prediction is correct"); 665 666 tageAltMatchProviderCorrect 667 .name(name() + ".tageAltMatchProviderCorrect") 668 .desc("Number of times TAGE Alt Match is the provider and " 669 "the prediction is correct"); 670 671 bimodalAltMatchProviderCorrect 672 .name(name() + ".bimodalAltMatchProviderCorrect") 673 .desc("Number of times TAGE Alt Match is the bimodal and it is the " 674 "provider and the prediction is correct"); 675 676 tageBimodalProviderCorrect 677 .name(name() + ".tageBimodalProviderCorrect") 678 .desc("Number of times there are no hits on the TAGE tables " 679 "and the bimodal prediction is correct"); 680 681 tageLongestMatchProviderWrong 682 .name(name() + ".tageLongestMatchProviderWrong") 683 .desc("Number of times TAGE Longest Match is the provider and " 684 "the prediction is wrong"); 685 686 tageAltMatchProviderWrong 687 .name(name() + ".tageAltMatchProviderWrong") 688 .desc("Number of times TAGE Alt Match is the provider and " 689 "the prediction is wrong"); 690 691 bimodalAltMatchProviderWrong 692 .name(name() + ".bimodalAltMatchProviderWrong") 693 .desc("Number of times TAGE Alt Match is the bimodal and it is the " 694 "provider and the prediction is wrong"); 695 696 tageBimodalProviderWrong 697 .name(name() + ".tageBimodalProviderWrong") 698 .desc("Number of times there are no hits on the TAGE tables " 699 "and the bimodal prediction is wrong"); 700 701 tageAltMatchProviderWouldHaveHit 702 .name(name() + ".tageAltMatchProviderWouldHaveHit") 703 .desc("Number of times TAGE Longest Match is the provider, " 704 "the prediction is wrong and Alt Match prediction was correct"); 705 706 tageLongestMatchProviderWouldHaveHit 707 .name(name() + ".tageLongestMatchProviderWouldHaveHit") 708 .desc("Number of times TAGE Alt Match is the provider, the " 709 "prediction is wrong and Longest Match prediction was correct"); 710 711 tageLongestMatchProvider 712 .init(nHistoryTables + 1) 713 .name(name() + ".tageLongestMatchProvider") 714 .desc("TAGE provider for longest match"); 715 716 tageAltMatchProvider 717 .init(nHistoryTables + 1) 718 .name(name() + ".tageAltMatchProvider") 719 .desc("TAGE provider for alt match"); 720} 721 | |
722TAGE* 723TAGEParams::create() 724{ 725 return new TAGE(this); 726} | 143TAGE* 144TAGEParams::create() 145{ 146 return new TAGE(this); 147} |