-
Notifications
You must be signed in to change notification settings - Fork 0
/
gshare.cc
219 lines (156 loc) · 5.97 KB
/
gshare.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include "cpu/pred/gshare.hh"
#include "base/bitfield.hh"
#include "base/intmath.hh"
#include "cpu/nativetrace.hh"
#include "arch/generic/vec_pred_reg.hh"
namespace gem5{
namespace branch_prediction{
GshareBP::GshareBP(const GshareBPParams ¶ms)
: BPredUnit(params),
globalHistory(params.numThreads, 0), // initialize global history register for each thread to 0
globalHistoryBits(params.globalPredictorSize), // number of bits in the global history register
choicePredictorSize(params.PHTPredictorSize), // size of the choice predictor (in entries)
choiceCtrBits(params.PHTCtrBits), // number of bits in the counters of the choice predictor
choiceCtrs(choicePredictorSize, SatCounter8(choiceCtrBits))
{
if(!isPowerOf2(choicePredictorSize)){
fatal("Invalid choice predictor size!\n");
}// check that choice predictor size is a power of 2
// Set up choiceHistoryMask
// this is equivalent to mask(log2(choicePredictorSize)
choiceHistoryMask = choicePredictorSize - 1;
//Setup the array of counters for the choice predictor.
//choicCtrs vektorunun boyutunu yeniden ayarlar
// choiceCtrs.resize(choicePredictorSize);
// initialize the counters in the choice predictor to have the specified number of bits
/* for (int i = 0; i < choicePredictorSize; ++i)
choiceCtrs[i].setBits(choiceCtrBits);*/
//Set up historyRegisterMask
historyRegisterMask = mask(globalHistoryBits);
// Set thresholds for the predictors' counters
// This is equivalent to (2^(Ctr))/2 - 1
choiceThreshold = (1ULL << (choiceCtrBits - 1)) - 1;
}
// helper function that calculates the index into the local history table
inline
unsigned
GshareBP::calcLocHistIdx(Addr &branch_addr)
{
// Get low order bits after removing instruction offset.
return (branch_addr >> instShiftAmt) & historyRegisterMask;
}
// helper function that updates the global history register when a branch is taken
inline
void
GshareBP::updateGlobalHistTaken(ThreadID tid)
{
// shift left by 1 and set the least significant bit to 1
globalHistory[tid] = (globalHistory[tid] << 1) | 1;
// apply historyRegisterMask to ensure only globalHistoryBits are used
globalHistory[tid] = globalHistory[tid] & historyRegisterMask;
}
// Update the global history register for a not taken branch
inline
void
GshareBP::updateGlobalHistNotTaken(ThreadID tid)
{
// Shift global history left by 1 bit and set the least significant bit to 0
globalHistory[tid] = (globalHistory[tid] << 1);
// Mask the global history with historyRegisterMask to keep it within the specified size
globalHistory[tid] = globalHistory[tid] & historyRegisterMask;
}
void
GshareBP::btbUpdate(ThreadID tid, Addr branch_addr, void * &bp_history)
{
// Clear the least significant bit of the global history
globalHistory[tid] &= (historyRegisterMask & ~1ULL);
}
bool GshareBP::lookup(ThreadID tid, Addr branch_addr, void *&bp_history){
//local history_idx is used to index into the local history table
unsigned local_history_idx;
//choise_prediction is used to store the prediction made by the choice predictor
bool choice_prediction;
//Calculate the index into the local history table
local_history_idx = calcLocHistIdx(branch_addr);
//Calculate the index into the choice predictor
unsigned choice_prediction_idx = (globalHistory[tid] & historyRegisterMask) ^ local_history_idx;
// Lookup in the choice predictor to see which one to use
choice_prediction = choiceThreshold < choiceCtrs[choice_prediction_idx & choiceHistoryMask];
/* eger thresholddan buyukse taken kucukse non taken demistik. burda indexdeki deger choiceCtrs vektorunde o indexindeki store edilen
counter objesinin read() metodu kullanılarak elde edilir.
*/
// Create BPHistory and pass it back to be recorded.
BPHistory *history = new BPHistory;
history->globalHistory = globalHistory[tid] & historyRegisterMask;
bp_history = (void *)history;
// Return the prediction made by the choice predictor
if (choice_prediction)
{
updateGlobalHistTaken(tid);
return true;
}
else
{
updateGlobalHistNotTaken(tid);
return false;
}
}
void
GshareBP::uncondBranch(ThreadID tid, Addr pc, void * &bp_history)
{
// Create BPHistory and pass it back to be recorded.
BPHistory *history = new BPHistory;
history->globalHistory = globalHistory[tid] & historyRegisterMask;
bp_history = static_cast<void *>(history);
updateGlobalHistTaken(tid);
}
void
GshareBP::update(ThreadID tid, Addr branch_addr, bool taken,
void *bp_history, bool squashed)
{
assert(bp_history);
BPHistory *history = static_cast<BPHistory *>(bp_history);
unsigned local_history_idx = calcLocHistIdx(branch_addr);
if (squashed) {
// Global history restore and update
globalHistory[tid] = (history->globalHistory << 1) | taken;
globalHistory[tid] &= historyRegisterMask;
return;
}
// there was a prediction.
unsigned choice_predictor_idx = (local_history_idx ^ history->globalHistory) & choiceHistoryMask;
if(taken)
{
choiceCtrs[choice_predictor_idx]++; //increment metodu vardı degistirdim
}
else
{
choiceCtrs[choice_predictor_idx]--; //decrement metodu vardı degistirdim
}
// We're done with this history, now delete it.
delete history;
}
void
GshareBP::squash(ThreadID tid, void *bp_history)
{
BPHistory *history = static_cast<BPHistory *>(bp_history);
// Restore global history to state prior to this branch.
globalHistory[tid] = history->globalHistory;
delete history;
}
/*GshareBP*
GshareBPParams::create()
{
return new GshareBP(this);
}*/
unsigned
GshareBP::getGHR(ThreadID tid, void *bp_history) const
{
return static_cast<BPHistory *>(bp_history)->globalHistory;
}
#ifdef DEBUG
int
GshareBP::BPHistory::newCount = 0;
#endif
}//namespace bp
}//name space gem5