Support performance counters (hopefully) in the caches. The DCache

should be fully wired up.
This commit is contained in:
jon
2020-12-14 18:10:06 +00:00
parent 982758cae7
commit 73d25bf8f5
4 changed files with 125 additions and 41 deletions

View File

@@ -245,6 +245,10 @@ instance BitVectorable #(EventsCoreMem, SizeOf#(HpmRpt), EventsCoreMemElements)
function Vector#(EventsCoreMemElements, HpmRpt) to_vector(EventsCoreMem e) =
reverse(unpack(pack(e)));
endinstance
instance BitVectorable #(EventsCache, SizeOf#(HpmRpt), EventsCacheElements) provisos (Bits #(EventsCache, m));
function Vector#(EventsCacheElements, HpmRpt) to_vector(EventsCache e) =
reverse(unpack(pack(e)));
endinstance
`endif
(* synthesize *)
@@ -1116,7 +1120,7 @@ module mkCore#(CoreId coreId)(Core);
Vector #(31, Bit #(Report_Width)) other_core_evts_vec = to_large_vector (hpm_core_events_reg);
Vector #(31, Bit #(Report_Width)) core_evts_vec = unpack(pack(mem_core_evts_vec) | pack(other_core_evts_vec));
Vector #(16, Bit #(Report_Width)) imem_evts_vec = replicate (0);//to_large_vector (near_mem.imem.events);
Vector #(16, Bit #(Report_Width)) dmem_evts_vec = replicate (0);//to_large_vector (near_mem.dmem.events);
Vector #(16, Bit #(Report_Width)) dmem_evts_vec = to_large_vector (dMem.events);
Vector #(32, Bit #(Report_Width)) external_evts_vec = replicate (0);//to_large_vector (w_external_evts);
let events = append (null_evt, core_evts_vec);

View File

@@ -45,6 +45,26 @@ import Connectable::*;
import GetPut::*;
import ClientServer::*;
`ifdef PERFORMANCE_MONITORING
typedef struct {
Bit#(8) evt_LD;
Bit#(8) evt_LD_MISS;
Bit#(8) evt_LD_MISS_LAT;
Bit#(8) evt_ST;
Bit#(8) evt_ST_MISS; // Unimplemented
Bit#(8) evt_ST_MISS_LAT; // Unimplemented
Bit#(8) evt_AMO;
Bit#(8) evt_AMO_MISS;
Bit#(8) evt_AMO_MISS_LAT;
Bit#(8) evt_TLB;
Bit#(8) evt_TLB_MISS; // Only leaf is stored in TLB thus a full
Bit#(8) evt_TLB_MISS_LAT; // walk must happen every miss
Bit#(8) evt_TLB_FLUSH;
Bit#(8) evt_EVICT;
} EventsCache deriving (Bits, FShow);
typedef TDiv#(SizeOf#(EventsCache),8) EventsCacheElements;
`endif
typedef enum {
I = 2'd0,
S = 2'd1,

View File

@@ -60,6 +60,10 @@ import CrossBar::*;
import Performance::*;
import LatencyTimer::*;
import RandomReplace::*;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import SpecialWires::*;
`endif
export L1CRqStuck(..);
export L1PRqStuck(..);
@@ -103,6 +107,9 @@ interface L1Bank#(
// performance
method Action setPerfStatus(Bool stats);
method Data getPerfData(L1DPerfType t);
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
endinterface
typedef struct {
@@ -191,6 +198,7 @@ module mkL1Bank#(
`endif
// performance
LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency
`ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) ldCnt <- mkCount(0);
@@ -202,43 +210,81 @@ module mkL1Bank#(
Count#(Data) ldMissLat <- mkCount(0);
Count#(Data) stMissLat <- mkCount(0);
Count#(Data) amoMissLat <- mkCount(0);
LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency
function Action incrReqCnt(MemOp op);
action
if(doStats) begin
case(op)
Ld: ldCnt.incr(1);
St: stCnt.incr(1);
Lr, Sc, Amo: amoCnt.incr(1);
endcase
end
endaction
endfunction
function Action incrMissCnt(MemOp op, cRqIdxT idx);
action
let lat <- latTimer.done(idx);
if(doStats) begin
case(op)
Ld: begin
ldMissLat.incr(zeroExtend(lat));
ldMissCnt.incr(1);
end
St: begin
stMissLat.incr(zeroExtend(lat));
stMissCnt.incr(1);
end
Lr, Sc, Amo: begin
amoMissLat.incr(zeroExtend(lat));
amoMissCnt.incr(1);
end
endcase
end
endaction
endfunction
`endif
`ifdef PERFORMANCE_MONITORING
Array #(Wire #(EventsCache)) perf_events <- mkDWireOR (2, unpack (0));
Reg #(EventsCache) perf_events_reg <- mkConfigReg(unpack(0));
rule update_events_reg;
perf_events_reg <= perf_events[0];
endrule
`endif
function Action incrReqCnt(MemOp op);
action
`ifdef PERF_COUNT
if(doStats) begin
case(op)
Ld: ldCnt.incr(1);
St: stCnt.incr(1);
Lr, Sc, Amo: amoCnt.incr(1);
endcase
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache events = unpack (0);
case(op)
Ld: events.evt_LD = 1;
St: events.evt_ST = 1;
Lr, Sc, Amo: events.evt_AMO = 1;
endcase
perf_events[0] <= events;
`endif
noAction;
endaction
endfunction
function Action incrMissCnt(MemOp op, cRqIdxT idx);
action
let lat <- latTimer.done(idx);
`ifdef PERF_COUNT
if(doStats) begin
case(op)
Ld: begin
ldMissLat.incr(zeroExtend(lat));
ldMissCnt.incr(1);
end
St: begin
stMissLat.incr(zeroExtend(lat));
stMissCnt.incr(1);
end
Lr, Sc, Amo: begin
amoMissLat.incr(zeroExtend(lat));
amoMissCnt.incr(1);
end
endcase
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache events = unpack (0);
case(op)
Ld: begin
events.evt_LD_MISS_LAT = saturating_truncate(lat);
events.evt_LD_MISS = 1;
end
St: begin
events.evt_ST_MISS_LAT = saturating_truncate(lat);
events.evt_ST_MISS = 1;
end
Lr, Sc, Amo: begin
events.evt_AMO_MISS_LAT = saturating_truncate(lat);
events.evt_AMO_MISS = 1;
end
endcase
perf_events[1] <= events;
`endif
noAction;
endaction
endfunction
function tagT getTag(Addr a) = truncateLSB(a);
@@ -274,10 +320,8 @@ module mkL1Bank#(
addr: r.addr,
mshrIdx: n
}));
`ifdef PERF_COUNT
// performance counter: cRq type
incrReqCnt(r.op);
`endif
if (verbose)
$display("%t L1 %m cRqTransfer_new: ", $time,
fshow(n), " ; ",
@@ -849,10 +893,8 @@ module mkL1Bank#(
("pRs must be a hit")
);
cRqHit(cOwner, procRq);
`ifdef PERF_COUNT
// performance counter: miss cRq
incrMissCnt(procRq.op, cOwner);
`endif
end
else begin
doAssert(False, ("pRs owner must match some cRq"));
@@ -1089,6 +1131,9 @@ module mkL1Bank#(
default: 0;
endcase);
endmethod
`ifdef PERFORMANCE_MONITORING
method EventsCache events = perf_events_reg;
`endif
endmodule
@@ -1320,4 +1365,13 @@ module mkL1Cache#(
end
return fold(\+ , d);
endmethod
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
EventsCache ret = unpack(0);
for(Integer i = 0; i < valueof(bankNum); i = i+1) begin
ret = unpack(pack(ret) | pack(banks[i].events));
end
return ret;
endmethod
`endif
endmodule

View File

@@ -178,6 +178,9 @@ interface DCoCache;
method Bool flush_done;
method Action resetLinkAddr;
interface Perf#(L1DPerfType) perf;
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
interface ChildCacheToParent#(L1Way, void) to_parent;
@@ -267,6 +270,9 @@ module mkDCoCache#(L1ProcResp#(DProcReqId) procResp)(DCoCache);
`endif
endmethod
endinterface
`ifdef PERFORMANCE_MONITORING
method EventsCache events = cache.events;
`endif
interface to_parent = cache.to_parent;