-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtagged_prefetcher.C
149 lines (131 loc) · 4.11 KB
/
tagged_prefetcher.C
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
/*
*
* File: prefetcher.C
* Author: Sat Garcia (sat@cs)
* Description: This simple prefetcher waits until there is a D-cache miss then
* requests location (addr + 16), where addr is the address that just missed
* in the cache.
*
*/
#include "prefetcher.h"
#include <stdio.h>
/* tagged prefetcher, prefetch the next block(s) based on when they
are accessed. Our state is a massive bit array indicated whether
or not an element is "tagged" - meaning that it has been issued as
a prefetcher request. Whenever the prefetcher request is used, we
prefetch the next block(s).*/
static char tags[STATE_SIZE];
/* private functions for prefetcher bit-array management*/
static
bool checkPrefetched(u_int32_t addr){
int bit_index, char_index, rem_bits;
char section, selector, result;
bit_index = addr % (STATE_SIZE * sizeof(char));
char_index = bit_index/BITS_PER_CHAR; //8 bits per char
rem_bits = bit_index - (char_index * BITS_PER_CHAR);
selector = 1;
selector = selector << rem_bits;
section = tags[char_index];
result = section & selector;
if(result > 0){
return true;
}else{
return false;
}
}
static
void markPrefetched(u_int32_t addr){
int bit_index, char_index, rem_bits;
char section, selector, result;
bit_index = addr % (STATE_SIZE * sizeof(char));
char_index = bit_index/BITS_PER_CHAR; //8 bits per char
rem_bits = bit_index - (char_index * BITS_PER_CHAR);
/*printf("For address %d, bit_index %d, char_index %d and rem_bits %d\n",
addr, bit_index, char_index, rem_bits); */
selector = 1;
selector = selector << rem_bits;
tags[char_index] = tags[char_index] | selector;
return;
}
static
void markUnPrefetched(u_int32_t addr){
int bit_index, char_index, rem_bits;
char section, selector, result;
bit_index = addr % (STATE_SIZE * sizeof(char));
char_index = bit_index/BITS_PER_CHAR; //8 bits per char
rem_bits = bit_index - (char_index * BITS_PER_CHAR);
selector = 1;
selector = selector << rem_bits;
tags[char_index] = tags[char_index] & (~selector);
return;
}
static
bool bitArrayTest(){
//u_int32_t baseTest = 0xA08A28AC; //prime bits marked
tags[0] = 0xff;
int i;
memset(tags, 0, STATE_SIZE);
for (i = 0; i < sizeof(u_int32_t) * 8; i+=2){
if(checkPrefetched(i)){
return false;
}
markPrefetched(i);
}
for (i = 0; i < sizeof(u_int32_t) * 8; i+=3){
markUnPrefetched(i);
}
for(i = 0; i < sizeof(u_int32_t) * 8; i++){
if((i % 2) == 0 && (i % 6) != 0 ){
if(!checkPrefetched(i)){
return false;
}
}else{
if(checkPrefetched(i)){
return false;
}
}
}
//printf("Value of first 32 bits of tags %x\n", *((int *)tags));
return true;
}
Prefetcher::Prefetcher() {
_ready = false;
/* mark all tags as not prefetched */
memset(tags, 0, STATE_SIZE);
/* if(bitArrayTest()){
printf("Bit array test passed!\n");
} */
}
bool Prefetcher::hasRequest(u_int32_t cycle) { return _ready; }
Request Prefetcher::getRequest(u_int32_t cycle) { return _nextReq; }
void Prefetcher::completeRequest(u_int32_t cycle) {
if(_req_left == 0){
_ready = false;
}else{
_req_left--;
_nextReq.addr = _nextReq.addr + L2_BLOCK_SIZE;
markPrefetched(_nextReq.addr); //mark this as a prefetched block
}
}
void Prefetcher::cpuRequest(Request req) {
/*if it is a hit and this was a prefetch address,
get the next one that hasn't been prefetched*/
if(req.HitL1 && checkPrefetched(req.addr) && !_ready){
_nextReq.addr = req.addr + L2_BLOCK_SIZE;
/*while(checkPrefetched(_nextReq.addr)){
_nextReq.addr += L2_BLOCK_SIZE;
printf("INFINITE LOOP!\n");
} */
markPrefetched(_nextReq.addr); //mark this as a prefetched block
_ready = true;
_req_left = NUM_REQS_PER_MISS - 1;
}else if(!_ready && !req.HitL1) {
/* this was a pure miss, fetch the next n blocks
regardless (even if prefetched, prob evicted from cache */
_nextReq.addr = req.addr + L2_BLOCK_SIZE;
_ready = true;
_req_left = NUM_REQS_PER_MISS - 1;
}
/* mark prefetch tag as 0 since CPU requested this */
markUnPrefetched(req.addr);
}