added some of the performance counters in the L2 TLB

- count L2 TLB accesses
- count L2 TLB misses
- count L2 TLB flushes
This commit is contained in:
Franz Fuchs
2021-04-01 15:15:32 +01:00
parent 6e157fff5a
commit ad044689cb
3 changed files with 53 additions and 5 deletions

View File

@@ -60,7 +60,7 @@ to the fact that they are Flute-only events)
- Mem cap load tag set – count when a tagged capability is loaded (0x1c)
- Mem cap store tag set – count when stage a tagged capability is stored (0x1d)
IMem, DMem L1 Cache, and LL Cache; events identical for all three, though some are irrelevant for the respective caches. IDs in format (IMem/DMem/LLC):
IMem, DMem L1 Cache, and LL Cache (including the respective TLBs); events identical for all three, though some are irrelevant for the respective caches. IDs in format (IMem/DMem/LLC):
- Load – count loads requested by cpu (0x20/0x30/unimplemented)
- Load miss – count loads missed (0x21/0x31/0x61)
- Load miss latency – count cycles waiting on a load miss (0x22/0x32/0x62)
@@ -70,10 +70,10 @@ IMem, DMem L1 Cache, and LL Cache; events identical for all three, though some a
- Amo – count atomic ops requested by cpu (unimplemented/0x36/unimplemented)
- Amo miss – count atomics missed (unimplemented/0x37/unimplemented)
- Amo miss latency – count cycles waiting on a atomics miss (unimplemented/0x38/unimplemented)
- Tlb – count tlb accesses (0x29/0x39/unimplemented)
- Tlb miss – count tlb missed (0x2a/0x3a/unimplemented)
- Tlb – count tlb accesses (0x29/0x39/0x69)
- Tlb miss – count tlb missed (0x2a/0x3a/0x6a)
- Tlb miss latency – count cycles waiting on a tlb miss (0x2b/0x3b/unimplemented)
- Tlb flush – count tlb flushes (0x2c/0x3c/unimplemented)
- Tlb flush – count tlb flushes (0x2c/0x3c/0x6c)
- Evict – count cache line evictions (unimplemented/unimplemented/unimplemented)

View File

@@ -1094,6 +1094,8 @@ module mkCore#(CoreId coreId)(Core);
`ifdef PERFORMANCE_MONITORING
// ================================================================
// Performance counters
// Each cache and TLB pair uses the same struct (EventsCache), but the cache accesses
// different fields than the TLB, which makes it safe to combine them
Reg#(EventsCache) events_llc_reg <- mkRegU;
Reg#(EventsCache) events_tgc_reg <- mkRegU;
@@ -1112,7 +1114,8 @@ module mkCore#(CoreId coreId)(Core);
EventsCache dataMem = unpack(pack(dMem.events) | pack(dTlb.events));
Vector #(16, Bit #(Report_Width)) dmem_evts_vec = to_large_vector (dataMem);
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);
EventsCache llMem = unpack(pack(events_llc_reg) | pack(l2Tlb.events));
Vector #(16, Bit #(Report_Width)) llc_evts_vec = to_large_vector (llMem);
Vector #(16, Bit #(Report_Width)) tgc_evts_vec = to_large_vector (events_tgc_reg);
let events = append (null_evt, core_evts_vec);

View File

@@ -54,6 +54,11 @@ import SetAssocTlb::*;
import L2SetAssocTlb::*;
import TranslationCache::*;
import LatencyTimer::*;
`ifdef PERFORMANCE_MONITORING
import PerformanceMonitor::*;
import CCTypes::*;
import BlueUtils::*;
`endif
// for SV39 only
@@ -114,6 +119,9 @@ interface L2Tlb;
// performace
interface Perf#(L2TlbPerfType) perf;
`ifdef PERFORMANCE_MONITORING
method EventsCache events;
`endif
endinterface
typedef FullAssocTlb#(`L2_TLB_HUGE_SIZE) L2FullAssocTlb;
@@ -277,6 +285,9 @@ module mkL2Tlb(L2Tlb::L2Tlb);
});
endrule
`endif
`ifdef PERFORMANCE_MONITORING
Array #(Reg #(EventsCache)) perf_events <- mkDRegOR (3, unpack (0));
`endif
// when flushing is true, since both I and D TLBs have finished flush and
// is waiting for L2 to flush, all I/D TLB req must have been responded.
@@ -289,6 +300,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
// check no req
doAssert(!rqFromCQ.notEmpty, "cannot have new req");
doAssert(readVEhr(0, pendValid) == replicate(False), "cannot have pending req");
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB_FLUSH = 1;
perf_events[2] <= ev;
`endif
endrule
rule doWaitFlush(flushing && waitFlushDone && tlb4KB.flush_done && transCache.flush_done);
@@ -402,6 +418,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
dataHugePageHitCnt.incr(1);
end
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB = 1;
perf_events[1] <= ev;
`endif
end
else if(resp4KB.hit) begin
@@ -411,6 +432,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
pageHit(entry);
// update 4KB array replacement, no need to touch MG array
tlb4KB.deqResp(Valid (resp4KB.way));
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB = 1;
perf_events[1] <= ev;
`endif
end
else begin
// miss, deq resp
@@ -429,6 +455,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
dataMissCnt.incr(1);
end
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB_MISS = 1;
perf_events[0] <= ev;
`endif
end
endrule
@@ -662,6 +693,12 @@ module mkL2Tlb(L2Tlb::L2Tlb);
child: cRq.child,
entry: Valid (entry)
});
`ifdef PERFORMANCE_MONITORING
// page table walks are counted as accesses
EventsCache ev = unpack(0);
ev.evt_TLB = 1;
perf_events[1] <= ev;
`endif
// update TLB array
if(entry.level > 0) begin
// add to mega/giga page tlb
@@ -675,6 +712,11 @@ module mkL2Tlb(L2Tlb::L2Tlb);
dataHugePageMissCnt.incr(1);
end
end
`endif
`ifdef PERFORMANCE_MONITORING
EventsCache ev = unpack(0);
ev.evt_TLB_MISS = 1;
perf_events[0] <= ev;
`endif
end
else begin
@@ -764,4 +806,7 @@ module mkL2Tlb(L2Tlb::L2Tlb);
`endif
endmethod
endinterface
`ifdef PERFORMANCE_MONITORING
method EventsCache events = perf_events[0];
`endif
endmodule