-
Notifications
You must be signed in to change notification settings - Fork 0
/
branch_predictor.cc
152 lines (130 loc) · 4.49 KB
/
branch_predictor.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
/*
* branch_predictor.cc
*
* Branch Predictor Class
* for Sniper Simulation
*
* < Chris Mark >
*
*/
#include "simulator.h"
#include "branch_predictor.h"
#include "one_bit_branch_predictor.h"
#include "pentium_m_branch_predictor.h"
#include "config.hpp"
#include "stats.h"
/* advcomparch: include file with nbit predictor. */
#include "NotTaken.h"
#include "btfntPredictor.h"
#include "nbit_branch_predictor.h"
#include "local_history_predictor.h"
#include "global_history_predictor.h"
#include "tournament_predictor.h"
#include "tournament_predictor_2.h"
BranchPredictor::BranchPredictor()
: m_correct_predictions(0)
, m_incorrect_predictions(0)
{
}
BranchPredictor::BranchPredictor(String name, core_id_t core_id)
: m_correct_predictions(0)
, m_incorrect_predictions(0)
{
registerStatsMetric(name, core_id, "num-correct", &m_correct_predictions);
registerStatsMetric(name, core_id, "num-incorrect", &m_incorrect_predictions);
}
BranchPredictor::~BranchPredictor()
{ }
UInt64 BranchPredictor::m_mispredict_penalty;
BranchPredictor* BranchPredictor::create(core_id_t core_id)
{
try
{
config::Config *cfg = Sim()->getCfg();
assert(cfg);
m_mispredict_penalty = cfg->getIntArray("perf_model/branch_predictor/mispredict_penalty", core_id);
String type = cfg->getStringArray("perf_model/branch_predictor/type", core_id);
if (type == "none")
{
return 0;
}
else if (type == "one_bit")
{
UInt32 size = cfg->getIntArray("perf_model/branch_predictor/size", core_id);
return new OneBitBranchPredictor("branch_predictor", core_id, size);
}
else if (type == "pentium_m")
{
return new PentiumMBranchPredictor("branch_predictor", core_id);
}
else if (type == "local")
{
UInt32 bht_ip_bits = cfg->getIntArray("perf_model/branch_predictor/bht_ip_bits", core_id);
UInt32 cntr_bits = cfg->getIntArray("perf_model/branch_predictor/cntr_bits", core_id);
UInt32 pht_ip_bits = cfg->getIntArray("perf_model/branch_predictor/pht_ip_bits", core_id);
UInt32 history_bits = cfg->getIntArray("perf_model/branch_predictor/history_bits", core_id);
return new LocalHistoryPredictor("branch_predictor", core_id, bht_ip_bits, pht_ip_bits, cntr_bits, history_bits);
}
else if (type == "global")
{
UInt32 bhr_length = cfg->getIntArray("perf_model/branch_predictor/bhr_length", core_id);
UInt32 cntr_bits = cfg->getIntArray("perf_model/branch_predictor/cntr_bits", core_id);
UInt32 pht_entries = cfg->getIntArray("perf_model/branch_predictor/pht_entries", core_id);
return new GlobalHistoryPredictor ("branch_predictor", core_id, bhr_length, pht_entries, cntr_bits);
}
else if (type == "static_not_taken")
{
return new NotTakenPredictor("branch_predictor", core_id);
}
else if (type == "btfnt")
{
return new btfntPredictor("branch_predictor", core_id);
}
else if (type == "nbit")
{
/* advcomparch: create new NbitBranchPredictor */
UInt32 index_bits = cfg->getIntArray("perf_model/branch_predictor/index_bits", core_id);
UInt32 cntr_bits = cfg->getIntArray("perf_model/branch_predictor/cntr_bits", core_id);
return new NbitBranchPredictor("branch_predictor", core_id, index_bits, cntr_bits);
}
else if (type == "Tournament")
{
UInt32 index_bits = cfg->getIntArray("perf_model/branch_predictor/index_bits", core_id);
UInt32 cntr_bits = cfg->getIntArray("perf_model/branch_predictor/cntr_bits", core_id);
return new TournamentBranchPredictor("branch_predictor", core_id, index_bits, cntr_bits);
}
else if (type == "Tournament2")
{
UInt32 index_bits = cfg->getIntArray("perf_model/branch_predictor/index_bits", core_id);
UInt32 cntr_bits = cfg->getIntArray("perf_model/branch_predictor/cntr_bits", core_id);
return new TournamentBranchPredictor2("branch_predictor", core_id, index_bits, cntr_bits);
}
else
{
LOG_PRINT_ERROR("Invalid branch predictor type.");
return 0;
}
}
catch (...)
{
LOG_PRINT_ERROR("Config info not available while constructing branch predictor.");
return 0;
}
return 0;
}
UInt64 BranchPredictor::getMispredictPenalty()
{
return m_mispredict_penalty;
}
void BranchPredictor::resetCounters()
{
m_correct_predictions = 0;
m_incorrect_predictions = 0;
}
void BranchPredictor::updateCounters(bool predicted, bool actual)
{
if (predicted == actual)
++m_correct_predictions;
else
++m_incorrect_predictions;
}