Cleanup: remove non-BRAM prefetchers

This commit is contained in:
Karlis Susters
2023-03-16 12:29:06 +00:00
parent 9c4da78c34
commit 65ed55cb8a

View File

@@ -576,59 +576,6 @@ module mkBRAMSingleWindowTargetPrefetcher(Prefetcher) provisos
endmethod
endmodule
module mkSingleWindowTargetPrefetcher(Prefetcher) provisos
();
Integer cacheLinesInRange = 2;
Reg#(LineAddr) rangeEnd <- mkReg(0); //Points to one CLine after end of range
Reg#(LineAddr) nextToAsk <- mkReg(0);
Reg#(LineAddr) lastChildRequest <- mkReg(0);
TargetTable#(64, 8) targetTable <- mkTargetTable;
//If hit outside window, reallocate window (test!)
method Action reportAccess(Addr addr, HitOrMiss hitMiss);
let cl = getLineAddr(addr);
if (hitMiss == HIT &&
rangeEnd - fromInteger(cacheLinesInRange) - 1 < cl &&
cl < rangeEnd) begin
let nextEnd = cl + fromInteger(cacheLinesInRange) + 1;
$display("%t Prefetcher report HIT %h, moving window end to %h", $time, addr, Addr'{nextEnd, '0});
rangeEnd <= nextEnd;
end
else if (hitMiss == MISS) begin
$display("%t Prefetcher report MISS %h", $time, addr);
//Reset window
nextToAsk <= cl + 1;
rangeEnd <= cl + fromInteger(cacheLinesInRange) + 1;
end
if (cl != lastChildRequest + 1 && cl != lastChildRequest && cl != lastChildRequest - 1) begin
$display("%t Prefetcher add target entry from addr %h to addr %h", $time, Addr'{lastChildRequest, '0}, addr);
targetTable.set(lastChildRequest, cl);
end
lastChildRequest <= cl;
endmethod
method ActionValue#(Addr) getNextPrefetchAddr if (nextToAsk != rangeEnd);
Addr retAddr;
let lastAsked = nextToAsk-1;
let entryMaybe <- targetTable.getAndRemove(lastAsked);
if (entryMaybe matches tagged Valid .cl) begin
//If have valid entry for the last requested cline, prefetch the stored target first
//Reset table entry, so on further calls we prefetch the next successive clines
//If we actually take the jump, the table entry will be restored
retAddr = {cl, '0};
$display("%t Prefetcher getNextPrefetchAddr requesting target entry %h", $time, retAddr);
end
else begin
//If no table entry, prefetch further in window
nextToAsk <= nextToAsk + 1;
retAddr = {nextToAsk, '0};
$display("%t Prefetcher getNextPrefetchAddr requesting next-line %h", $time, retAddr);
end
return retAddr;
endmethod
endmodule
module mkBRAMMultiWindowTargetPrefetcher(Prefetcher)
provisos(
NumAlias#(numWindows, 4),
@@ -761,123 +708,6 @@ provisos(
endmodule
module mkMultiWindowTargetPrefetcher(Prefetcher)
provisos(
NumAlias#(numWindows, 4),
Alias#(windowIdxT, Bit#(TLog#(numWindows)))
);
Integer cacheLinesInRange = 2;
Vector#(numWindows, Reg#(StreamEntry)) streams
<- replicateM(mkReg(StreamEntry {rangeEnd: '0, nextToAsk: '0}));
Vector#(numWindows, Reg#(windowIdxT)) shiftReg <- genWithM(compose(mkReg, fromInteger));
Reg#(LineAddr) lastChildRequest <- mkReg(0);
TargetTable#(64, 8) targetTable <- mkTargetTable;
function Action moveWindowToFront(windowIdxT window) =
action
if (shiftReg[0] == window) begin
end
else if (shiftReg[1] == window) begin
shiftReg[0] <= window;
shiftReg[1] <= shiftReg[0];
end
else if (shiftReg[2] == window) begin
shiftReg[0] <= window;
shiftReg[1] <= shiftReg[0];
shiftReg[2] <= shiftReg[1];
end
else if (shiftReg[3] == window) begin
shiftReg[0] <= window;
shiftReg[1] <= shiftReg[0];
shiftReg[2] <= shiftReg[1];
shiftReg[3] <= shiftReg[2];
end
endaction;
function ActionValue#(Maybe#(windowIdxT)) getMatchingWindow(LineAddr cl) =
actionvalue
//Finds the first window that contains cache line
function Bool pred(StreamEntry se);
//TODO < gives 100 cycles less??????
return (se.rangeEnd - fromInteger(cacheLinesInRange) - 1 <= cl
&& cl < se.rangeEnd);
endfunction
//Find first window that contains cache line cl
if (findIndex(pred, readVReg(streams)) matches tagged Valid .idx) begin
return Valid(pack(idx));
end
else begin
return Invalid;
end
endactionvalue;
// test: allocate new window on hit too (mostly for target prefetching)
method Action reportAccess(Addr addr, HitOrMiss hitMiss);
//Check if any stream line matches request
//If so, advance that stream line and advance LRU shift reg
//Otherwise if miss, allocate new stream line, and shift LRU reg completely,
let cl = getLineAddr(addr);
// Update window prefetcher
let idxMaybe <- getMatchingWindow(cl);
if (idxMaybe matches tagged Valid .idx) begin
moveWindowToFront(pack(idx)); //Update window as just used
let newRangeEnd = getLineAddr(addr) + fromInteger(cacheLinesInRange) + 1;
if (hitMiss == HIT) begin
$display("%t Prefetcher report HIT %h, moving window end to %h for window idx %h",
$time, addr, Addr'{newRangeEnd, '0}, idx);
streams[idx].rangeEnd <= newRangeEnd;
end
else if (hitMiss == MISS) begin
//Also reset nextToAsk on miss
$display("%t Prefetcher report MISS %h, moving window end to %h for window idx %h",
$time, addr, Addr'{newRangeEnd, '0}, idx);
streams[idx] <=
StreamEntry {nextToAsk: getLineAddr(addr) + 1,
rangeEnd: newRangeEnd};
end
end
else if (hitMiss == MISS) begin
$display("%t Prefetcher report MISS %h, allocating new window, idx %h", $time, addr, shiftReg[3]);
streams[shiftReg[3]] <=
StreamEntry {nextToAsk: getLineAddr(addr) + 1,
rangeEnd: getLineAddr(addr) + fromInteger(cacheLinesInRange) + 1};
shiftReg[0] <= shiftReg[3];
shiftReg[1] <= shiftReg[0];
shiftReg[2] <= shiftReg[1];
shiftReg[3] <= shiftReg[2];
end
// Update target prefetcher
if (cl != lastChildRequest + 1 && cl != lastChildRequest && cl != lastChildRequest - 1) begin
$display("%t Prefetcher add target entry from addr %h to addr %h", $time, Addr'{lastChildRequest, '0}, addr);
targetTable.set(lastChildRequest, cl);
end
lastChildRequest <= cl;
endmethod
method ActionValue#(Addr) getNextPrefetchAddr
if (streams[shiftReg[0]].nextToAsk != streams[shiftReg[0]].rangeEnd);
Addr retAddr;
let lastAsked = streams[shiftReg[0]].nextToAsk-1;
let clMaybe <- targetTable.getAndRemove(lastAsked);
if (clMaybe matches tagged Valid .cl) begin
//If have valid entry for the last requested cline, prefetch the stored target first
//Reset table entry, so on further calls we prefetch the next successive clines
//If we actually take the jump, the table entry will be restored
retAddr = {cl, '0};
$display("%t Prefetcher getNextPrefetchAddr requesting target entry %h", $time, retAddr);
end
else begin
streams[shiftReg[0]].nextToAsk <= streams[shiftReg[0]].nextToAsk + 1;
retAddr = Addr'{streams[shiftReg[0]].nextToAsk, '0}; //extend cache line address to regular address
$display("%t Prefetcher getNextPrefetchAddr requesting %h from window idx %h", $time, retAddr, shiftReg[0]);
end
return retAddr;
endmethod
endmodule
module mkBRAMMarkovPrefetcher(Prefetcher) provisos
(
NumAlias#(maxChainLength, 2),
@@ -942,59 +772,6 @@ module mkBRAMMarkovPrefetcher(Prefetcher) provisos
endmodule
module mkMarkovPrefetcher(Prefetcher) provisos
(
NumAlias#(maxChainLength, 2),
Alias#(chainLengthT, Bit#(TLog#(TAdd#(maxChainLength,1))))
);
Reg#(LineAddr) lastLastChildRequest <- mkReg(0);
Reg#(LineAddr) lastChildRequest <- mkReg(0);
TargetTable#(64, 8) targetTable <- mkTargetTable;
// Stores how many prefetches we can still do in the current chain
Reg#(chainLengthT) chainNumberToPrefetch <- mkReg(0);
Reg#(LineAddr) chainNextToPrefetch <- mkReg(?);
method Action reportAccess(Addr addr, HitOrMiss hitMiss);
let cl = getLineAddr(addr);
if (cl != lastChildRequest + 1 && cl != lastChildRequest && cl != lastChildRequest - 1) begin
$display("%t Prefetcher report %s add target entry from addr %h to addr %h",
$time, hitMiss == HIT ? "HIT" : "MISS", Addr'{lastChildRequest, '0}, addr);
targetTable.set(lastChildRequest, cl);
end
lastChildRequest <= cl;
lastLastChildRequest <= lastChildRequest;
if (lastLastChildRequest != cl) begin
//Don't start markov chain if its very recent
let x <- targetTable.getAndRemove(cl);
if (x matches tagged Valid .nextCl) begin
//Start new prefetch chain
$display("%t Prefetcher start new chain with %h", $time, addr);
chainNextToPrefetch <= nextCl;
chainNumberToPrefetch <= fromInteger(valueOf(maxChainLength));
end
end
endmethod
method ActionValue#(Addr) getNextPrefetchAddr if
(chainNumberToPrefetch != 0);
let x <- targetTable.getAndRemove(chainNextToPrefetch);
if (x matches tagged Valid .nextCl) begin
chainNumberToPrefetch <= chainNumberToPrefetch - 1;
chainNextToPrefetch <= nextCl;
end
else begin
//End chain here
chainNumberToPrefetch <= 0;
end
Addr retAddr = {chainNextToPrefetch, '0};
$display("%t Prefetcher getNextPrefetchAddr requesting chain entry %h", $time, retAddr);
return retAddr;
endmethod
endmodule
module mkBlockPrefetcher(Prefetcher) provisos (
NumAlias#(numLinesEachWay, 1),
Alias#(lineCountT, Bit#(TLog#(TAdd#(numLinesEachWay, 1))))
@@ -1077,120 +854,6 @@ typedef struct {
Bit#(4) cLinesPrefetched; //Stores how many cache lines have been prefetched for this instruction
} StrideEntry deriving (Bits, Eq, FShow);
module mkStridePCPrefetcher(PCPrefetcher)
provisos(
NumAlias#(historyLen, 8),
NumAlias#(strideTableSize, 64),
NumAlias#(cLinesAheadToPrefetch, 3), // TODO fetch more if have repeatedly hit an entry, and if stride big
Alias#(strideTableIndexT, Bit#(TLog#(strideTableSize))),
Alias#(historyVecIndexT, Bit#(TLog#(historyLen)))
);
Reg#(Vector#(historyLen, Tuple2#(strideTableIndexT, Addr))) historyVec <- mkReg(replicate(?));
Vector#(strideTableSize, Reg#(StrideEntry)) strideTable <- replicateM(mkReg(unpack(0)));
function Maybe#(historyVecIndexT) getNextPrefetchHistoryIndex;
function Bool canPrefetch(Tuple2#(strideTableIndexT, Addr) entry);
strideTableIndexT idx = tpl_1(entry);
return (strideTable[idx].state == STEADY &&
strideTable[idx].cLinesPrefetched !=
fromInteger(valueof(cLinesAheadToPrefetch)));
endfunction
//Find first entry that allows more prefetches
case (findIndex(canPrefetch, historyVec)) matches
tagged Valid .historyIdx: return Valid(pack(historyIdx));
Invalid: return Invalid;
endcase
endfunction
method Action reportAccess(Addr addr, Bit#(16) pcHash, HitOrMiss hitMiss);
//Find slot in vector
//if miss and slot empty
//if slot init, put address, stride and move to transit
//if slot transit or steady, verify stride, and move to steady
// also put last_prefetched
//if stride wrong, move to transit
strideTableIndexT index = truncate(pcHash);
Reg#(StrideEntry) se = strideTable[index];
StrideEntry seNext = se;
Bit#(13) observedStride = {1'b0, addr[11:0]} - {1'b0, se.lastAddr};
$writeh("%t Stride Prefetcher reportAccess ", $time,
fshow(hitMiss), " ", addr,
". Entry ", index, " state is ", fshow(se.state));
if (se.state == EMPTY) begin
if (hitMiss == MISS) begin
seNext.lastAddr = truncate(addr);
seNext.state = INIT;
$display(", allocate entry");
end
else begin
$display(", ignore");
end
end
else if (se.state == INIT && observedStride != 0) begin
seNext.stride = observedStride;
seNext.state = TRANSIENT;
seNext.lastAddr = truncate(addr);
$display(", set stride to %h", seNext.stride);
end
else if ((se.state == TRANSIENT || se.state == STEADY) && observedStride != 0) begin
if (observedStride == se.stride) begin
if (se.state == TRANSIENT) begin
//Here we transition from TRANSIENT to STEADY, so init this field
seNext.cLinesPrefetched = 0;
end
else begin
//state == STEADY
if (se.lastAddr[11:6] != addr[11:6]) begin
//This means we have crossed a cache line since last access
seNext.cLinesPrefetched =
(se.cLinesPrefetched == 0) ? 0 : se.cLinesPrefetched - 1;
end
end
seNext.state = STEADY;
seNext.lastAddr = truncate(addr);
historyVec <= shiftInAt0(historyVec, tuple2(index, addr));
$display(", stride %h is confirmed!", seNext.stride);
end
else begin
seNext.state = TRANSIENT;
seNext.stride = observedStride;
seNext.lastAddr = truncate(addr);
$display(", old stride is broken! New stride: %h", seNext.stride);
end
end
else
$display("");
se <= seNext;
endmethod
method ActionValue#(Addr) getNextPrefetchAddr if
(getNextPrefetchHistoryIndex() matches tagged Valid .historyIdx);
match {.strideIdx, .fullAddr} = historyVec[historyIdx];
Reg#(StrideEntry) se = strideTable[strideIdx];
se.cLinesPrefetched <= se.cLinesPrefetched + 1;
Bit#(13) strideToUse;
Bit#(13) cLineSize = fromInteger(valueof(DataSz));
if (se.stride[12] == 1 && se.stride > -cLineSize) begin
//stride is negative and jumps less than one cline
strideToUse = -cLineSize;
end
else if (se.stride[12] == 0 && se.stride < cLineSize) begin
//stride is positive and jumps less than one cline
strideToUse = cLineSize;
end
else begin
strideToUse = se.stride;
end
let reqAddr = fullAddr +
(signExtend(strideToUse) * zeroExtend(se.cLinesPrefetched + 1));
$display("%t Stride Prefetcher getNextPrefetchAddr requesting %h for entry %h", $time, reqAddr, strideIdx);
return reqAddr;
endmethod
endmodule
module mkBRAMStridePCPrefetcher(PCPrefetcher)
provisos(
NumAlias#(strideTableSize, 512),