-
Notifications
You must be signed in to change notification settings - Fork 141
Decouple BTB and BP #613
Comments
@yanlo In my opinion, it would be natural for you to continue by doing this. In the end, you'll have understanding of all BPU pipeline and hopefully describe it on Wiki. |
Hi, I am back! There is what I've found out:
What concerns |
My strategy would be to separate things by doing a lot of small steps. For instance, to separate BTB and BP entry I would start by morphing this: template<typename T> // T is a joined BTB and BP entry
class BP final: public BaseBP
{
std::vector<std::vector<T>> data;
CacheTagArray tags; to this: template<typename T> // T is BP entry
class BP final: public BaseBP
{
struct BTBEntry {
bool valid;
Addr target;
};
struct Entry {
T direction;
BTBEntry target;
};
std::vector<std::vector<Entry>> data;
CacheTagArray tags; Then you'll naturaly fix all the |
Could you please explain me the general purpose of Entries? As I understand:
I see in static Map generate_map() {
Map my_map;
my_map.emplace("always_taken", std::make_unique<BPCreator<BPEntryAlwaysTaken>>());
my_map.emplace("always_not_taken", std::make_unique<BPCreator<BPEntryAlwaysNotTaken>>());
my_map.emplace("backward_jumps", std::make_unique<BPCreator<BPEntryBackwardJumps>>());
my_map.emplace("saturating_one_bit", std::make_unique<BPCreator<BPEntryOneBit>>());
my_map.emplace("saturating_two_bits", std::make_unique<BPCreator<BPEntryTwoBit>>());
my_map.emplace("adaptive_two_levels", std::make_unique<BPCreator<BPEntryAdaptive<2>>>());
return my_map;
} Why do we need to map here? |
I've read wiki where it is written:
But still it doesn't help me |
To deploy things separately. When you update the cache implementation, you do not care about what that cache holds (data, tags, simple BP entry, complicated BP entry etc.). In opposite, if you wish to add a new branch prediction algorithm — and you did that once — you do not have change cache structure. If it was done otherwise, code would be extremely tangled, hardly testable and maintainable.
That's an example of Abstract Factory pattern. We need it to hide the internals of BP implementations from its users — they just have to pass a string, and factory creates an instance of BP cache holding the entries for the particular branch prediction mode. |
Great. Now you can remove target variable from BPEntry, so all targets should be fetched from BTEntry. |
As I see What type T is used while creating BP class object? |
template<typename T> // T is BP entry
class BP final: public BaseBP
{ T is a name for template parameter. Please check what we use as the actual template parameters for BP. |
Yes, I see. As I understand I must see something like |
Here it is mipt-mips/simulator/modules/fetch/bpu/bpu.cpp Lines 112 to 137 in 7912021
|
Current implementation mixes two entities: BP (which predicts taken/not taken) and BTB (branch target buffer, predicts address of the branch).
There are 3 types of branches:
Only 2nd need T/NT branch prediction, as others are taken by definition.
All of three need BTB to predict target, and penalty for BTB mispredict is small for first two types, and higher for the last type.
The idea is to leave current BP modes only as BP modes (taken/not taken) and create a separate buffer for branch targets. It should be made as a separate cache structure with interfaces similar to the BP.
The road map goes as following:
The text was updated successfully, but these errors were encountered: