Stride: block prefetches out of page bounds, and reduce stride bit length

This commit is contained in:
Karlis Susters
2023-04-21 16:05:10 +01:00
parent b5a3a78e58
commit 754627d4e8
2 changed files with 35 additions and 13 deletions

View File

@@ -1357,7 +1357,7 @@ typedef enum {
typedef struct {
Bit#(12) lastAddr;
Int#(13) stride;
Int#(12) stride;
Bit#(2) cLinesPrefetched; //Stores how many cache lines have been prefetched for this instruction
StrideState2 state;
} StrideEntry2 deriving (Bits, Eq, FShow);
@@ -1398,7 +1398,7 @@ provisos(
StrideEntry2 se = strideTable.rdResp;
strideTable.deqRdResp;
StrideEntry2 seNext = se;
Int#(13) observedStride = unpack({1'b0, addr[11:0]} - {1'b0, se.lastAddr});
Int#(12) observedStride = unpack(addr[11:0] - se.lastAddr);
$writeh("%t Stride Prefetcher updateStrideEntry ", $time,
fshow(hitMiss), " ", addr,
". Entry ", index, " state is ", fshow(se.state));
@@ -1443,7 +1443,7 @@ provisos(
//We jump to some other random location, so reset number of lines prefetched
seNext.cLinesPrefetched = 0;
seNext.state = INIT;
$display(", random jump! Move to INIT, don't reset stride");
$display(", random jump (%x)! Move to INIT, don't reset stride", observedStride);
end
seNext.lastAddr = truncate(addr);
end
@@ -1469,20 +1469,23 @@ provisos(
//If this rule is looping, then we'll have a valid cLinesPrefetchedLatest
Bit#(2) cLinesPrefetched = fromMaybe(se.cLinesPrefetched, cLinesPrefetchedLatest);
Int#(16) cLineSize = fromInteger(valueof(DataSz));
Int#(16) strideToUse = signExtend(se.stride);
if (abs(strideToUse) < cLineSize) begin
strideToUse = (strideToUse < 0) ? -cLineSize : cLineSize;
strideToUse = (strideToUse < 0) ? -cLineSize : cLineSize;
strideToUse = (strideToUse < 0) ? -cLineSize : cLineSize;
end
Bit#(16) jumpDist = pack(strideToUse) * zeroExtend(cLinesPrefetched+1);
let reqAddr = addr + signExtend(jumpDist);
if (se.state == STEADY &&
cLinesPrefetched !=
fromInteger(valueof(cLinesAheadToPrefetch))) begin
fromInteger(valueof(cLinesAheadToPrefetch)) &&
reqAddr[63:12] == addr[63:12] //Check if same page
) begin
//can prefetch
Int#(13) cLineSize = fromInteger(valueof(DataSz));
Int#(13) strideToUse = se.stride;
if (abs(strideToUse) < cLineSize) begin
strideToUse = (strideToUse < 0) ? -cLineSize : cLineSize;
end
Bit#(13) jumpDist = pack(strideToUse) * zeroExtend(cLinesPrefetched+1);
let reqAddr = addr + signExtend(jumpDist);
addrToPrefetch.enq(reqAddr);
// We will still be processing this StrideEntry next cycle,
// so hold off any potential read requests until we do a writeback

View File

@@ -990,6 +990,25 @@ module mkStride2PCPrefetcherTest(Empty);
let x <- p.getNextPrefetchAddr;
doAssert(x == 'h900000b0, "test fail!");
endaction
// -- test blocking on page boundaries
action p.reportAccess('ha0000000, 'h006c, MISS); endaction
action p.reportAccess('ha0000400, 'h006c, MISS); endaction
action p.reportAccess('ha0000800, 'h006c, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'ha0000c00, "test fail!");
endaction
action p.reportAccess('ha0000c00, 'h006c, MISS); endaction
action p.reportAccess('hb0000000, 'h006c, MISS); endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'hb0000400, "test fail!");
endaction
action
let x <- p.getNextPrefetchAddr;
doAssert(x == 'hb0000800, "test fail!");
endaction
endseq
);
endmodule