Implement a couple Cache counters in the LLCache.

These aren't too useful... We don't seem to have normal counters for
loads and stores in the baseline.
This commit is contained in:
jon
2020-12-15 18:16:21 +00:00
parent 17a7a32092
commit fa9931b64c
6 changed files with 69 additions and 38 deletions

View File

@@ -216,6 +216,9 @@ interface Core;
method Bit#(32) debugRename;
`endif
`ifdef PERFORMANCE_MONITORING
method Action events_llc(EventsCache events);
`endif
endinterface
// fixpoint to instantiate modules
@@ -1107,6 +1110,7 @@ module mkCore#(CoreId coreId)(Core);
// ================================================================
// Performance counters
Reg#(EventsCache) events_llc_reg <- mkRegU;
rule report_events;
hpm_core_events[2] <= unpack(pack(commitStage.events));
endrule
@@ -1118,11 +1122,13 @@ module mkCore#(CoreId coreId)(Core);
Vector #(16, Bit #(Report_Width)) imem_evts_vec = to_large_vector (iMem.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);
Vector #(16, Bit #(Report_Width)) llc_evts_vec = to_large_vector (events_llc_reg);
let events = append (null_evt, core_evts_vec);
events = append (events, imem_evts_vec);
events = append (events, dmem_evts_vec);
events = append (events, external_evts_vec);
events = append (events, llc_evts_vec);
(* fire_when_enabled, no_implicit_conditions *)
rule rl_send_perf_evts;
@@ -1522,4 +1528,8 @@ module mkCore#(CoreId coreId)(Core);
endmethod
`endif
`ifdef PERFORMANCE_MONITORING
method events_llc = events_llc_reg._write;
`endif
endmodule

View File

@@ -188,6 +188,14 @@ module mkProc (Proc_IFC);
statReqs.deq;
endrule
`ifdef PERFORMANCE_MONITORING
rule broadcastPerfEvents;
for(Integer j = 0; j < valueof(CoreNum); j = j+1) begin
core[j].events_llc(llc.events);
end
endrule
`endif
// ================================================================
// Stub out deadlock and renameDebug interfaces

View File

@@ -252,10 +252,8 @@ module mkIBank#(
}));
// enq to indexQ for in order resp
cRqIndexQ.enq(n);
`ifdef PERF_COUNT
// performance counter: cRq type
incrReqCnt;
`endif
if (verbose)
$display("%t I %m cRqTransfer: ", $time,
fshow(n), " ; ",
@@ -640,10 +638,8 @@ module mkIBank#(
"pRs must be a hit"
);
cRqHit(cOwner, procRq);
`ifdef PERF_COUNT
// performance counter: miss cRq
incrMissCnt(cOwner);
`endif
end
else begin
doAssert(False, ("pRs owner must match some cRq"));

View File

@@ -51,6 +51,10 @@ import LatencyTimer::*;
import Cntrs::*;
import ConfigReg::*;
import RandomReplace::*;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import BlueUtils::*;
`endif
export LLCRqStuck(..);
export LLBank(..);
@@ -102,6 +106,9 @@ interface LLBank#(
// performance
method Action setPerfStatus(Bool stats);
method Data getPerfData(LLCPerfType t);
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
endinterface
typedef struct {
@@ -219,6 +226,7 @@ module mkLLBank#(
`endif
// performance
LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency
`ifdef PERF_COUNT
Reg#(Bool) doStats <- mkConfigReg(False);
Count#(Data) dmaMemLdCnt <- mkCount(0);
@@ -233,25 +241,34 @@ module mkLLBank#(
Count#(Data) upRespDataCnt <- mkCount(0);
Count#(Data) dmaLdReqCnt <- mkCount(0);
Count#(Data) dmaStReqCnt <- mkCount(0);
LatencyTimer#(cRqNum, 10) latTimer <- mkLatencyTimer; // max 1K cycle latency
function Action incrMissCnt(cRqIndexT idx, Bool isDma);
action
let lat <- latTimer.done(idx);
if(doStats) begin
if(isDma) begin
dmaMemLdCnt.incr(1);
dmaMemLdLat.incr(zeroExtend(lat));
end
else begin
normalMemLdCnt.incr(1);
normalMemLdLat.incr(zeroExtend(lat));
end
end
endaction
endfunction
`endif
`ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsCache)) perf_events <- mkDRegOR (2, unpack (0));
`endif
function Action incrMissCnt(cRqIndexT idx, Bool isDma);
action
let lat <- latTimer.done(idx);
`ifdef PERF_COUNT
if(doStats) begin
if(isDma) begin
dmaMemLdCnt.incr(1);
dmaMemLdLat.incr(zeroExtend(lat));
end
else begin
normalMemLdCnt.incr(1);
normalMemLdLat.incr(zeroExtend(lat));
end
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache events = unpack (0);
events.evt_LD_MISS_LAT = saturating_truncate(lat); // Don't support seperate DMA counts.
events.evt_LD_MISS = 1;
perf_events[1] <= events;
`endif
endaction
endfunction
function tagT getTag(Addr a) = truncateLSB(a);
@@ -515,10 +532,8 @@ module mkLLBank#(
fshow(cRq), " ; ",
fshow(cSlot), " ; "
);
`ifdef PERF_COUNT
// performance counter: normal miss lat and cnt
incrMissCnt(n, False);
`endif
endrule
// this mem resp is just for a DMA req, won't go into pipeline to refill cache
@@ -530,10 +545,8 @@ module mkLLBank#(
// save data into cRq mshr & send to DMA resp IndexQ
cRqMshr.mRsDeq.setData(mRs.id.mshrIdx, Valid (mRs.data));
rsLdToDmaIndexQ_mRsDeq.enq(mRs.id.mshrIdx);
`ifdef PERF_COUNT
// performance counter: dma miss lat and cnt
incrMissCnt(mRs.id.mshrIdx, True);
`endif
endrule
// send rd/wr to mem
@@ -572,10 +585,8 @@ module mkLLBank#(
$display("%t LL %m sendToM: load only: ", $time, fshow(msg));
doAssert(!isValid(data), "cannot have data");
doAssert(!doLdAfterReplace, "doLdAfterReplace should be false");
`ifdef PERF_COUNT
// performance counter: start miss timer
latTimer.start(n);
`endif
`ifdef DEBUG_DMA
if(cRq.id matches tagged Dma .dmaId) begin
dmaRdMissQ.enq(dmaId); // DMA read takes effect
@@ -619,10 +630,8 @@ module mkLLBank#(
doLdAfterReplace <= False;
if (verbose)
$display("%t LL %m sendToM: rep then ld: ld: ", $time, fshow(msg));
`ifdef PERF_COUNT
// performance counter: start miss timer
latTimer.start(n);
`endif
end
else begin // do write back part
toMemT msg = Wb (WbMemRs {
@@ -1531,6 +1540,9 @@ module mkLLBank#(
default: 0;
endcase);
endmethod
`ifdef PERFORMANCE_MONITORING
method EventsCache events = perf_events[0];
`endif
endmodule
// Scheduling notes
@@ -1593,4 +1605,3 @@ endmodule
// -- this cRq is different from that in mRsDeq
// -- this cRq is different from that in sendRsToC/sendRsToDma
// -- XXX this cRq may be the same as that in sendRqToC!!!

View File

@@ -13,7 +13,7 @@
//
// This work was supported by NCSC programme grant 4212611/RFA 15971 ("SafeBet").
//-
//
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@@ -21,10 +21,10 @@
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -254,6 +254,9 @@ interface LLCache;
interface Get#(LLCStuck) cRqStuck;
// performance
interface Perf#(LLCPerfType) perf;
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
endinterface
`ifdef SECURITY
@@ -462,4 +465,7 @@ module mkLLCache(LLCache);
`endif
endmethod
endinterface
`ifdef PERFORMANCE_MONITORING
method EventsCache events = cache.events;
`endif
endmodule

View File

@@ -1041,10 +1041,10 @@ endfunction
function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc));
`ifdef PERFORMANCE_MONITORING
typedef 96 No_Of_Evts;
typedef 8 Report_Width;
typedef 64 Counter_Width;
typedef 29 No_Of_Ctrs;
typedef 112 No_Of_Evts;
typedef 8 Report_Width;
typedef 64 Counter_Width;
typedef 29 No_Of_Ctrs;
typedef struct {
SupCnt evt_REDIRECT;