diff options
author | Nilay Vaish <nilay@cs.wisc.edu> | 2015-09-05 09:35:39 -0500 |
---|---|---|
committer | Nilay Vaish <nilay@cs.wisc.edu> | 2015-09-05 09:35:39 -0500 |
commit | 740984b30be923e0c171a52fe357a05016fe08c0 (patch) | |
tree | 909369348aaf57d64a23b9b110d5ca81d512bfca /src/mem/protocol | |
parent | 8f29298bc7a9aee1572ba3de66ed12db5995509c (diff) | |
download | gem5-740984b30be923e0c171a52fe357a05016fe08c0.tar.xz |
ruby: call setMRU from L1 controllers, not from sequencer
Currently the sequencer calls the function setMRU that updates the replacement
policy structures with the first level caches. While functionally this is
correct, the problem is that this requires calling findTagInSet() which is an
expensive function. This patch removes the calls to setMRU from the sequencer.
All controllers should now update the replacement policy on their own.
The set and the way index for a given cache entry can be found within the
AbstractCacheEntry structure. Use these indicies to update the replacement
policy structures.
Diffstat (limited to 'src/mem/protocol')
-rw-r--r-- | src/mem/protocol/MESI_Three_Level-L0cache.sm | 28 | ||||
-rw-r--r-- | src/mem/protocol/MESI_Two_Level-L1cache.sm | 29 | ||||
-rw-r--r-- | src/mem/protocol/MI_example-cache.sm | 4 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_directory-L1cache.sm | 17 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-L1cache.sm | 25 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_hammer-cache.sm | 35 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_Types.sm | 1 |
7 files changed, 107 insertions, 32 deletions
diff --git a/src/mem/protocol/MESI_Three_Level-L0cache.sm b/src/mem/protocol/MESI_Three_Level-L0cache.sm index 4a0766ce8..7e8626dc9 100644 --- a/src/mem/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/protocol/MESI_Three_Level-L0cache.sm @@ -459,21 +459,38 @@ machine(L0Cache, "MESI Directory L0 Cache") } } - action(h_load_hit, "h", desc="If not prefetch, notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="If not prefetch, notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } - action(hx_load_hit, "hx", desc="If not prefetch, notify sequencer the load completed.") { + action(h_ifetch_hit, "hi", desc="If not prefetch, notify sequencer the ifetch completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Icache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk); + } + + action(hx_load_hit, "hxd", desc="notify sequencer the load completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk, true); + } + + action(hx_ifetch_hit, "hxi", desc="notify sequencer the ifetch completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, true); } action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk); cache_entry.Dirty := true; } @@ -481,6 +498,7 @@ machine(L0Cache, "MESI Directory L0 Cache") action(hhx_store_hit, "\hx", desc="If not prefetch, notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, true); cache_entry.Dirty := true; } @@ -625,7 +643,7 @@ machine(L0Cache, "MESI Directory L0 Cache") } transition({S,E,M}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -712,7 +730,7 @@ machine(L0Cache, "MESI Directory L0 Cache") transition(Inst_IS, Data, S) { u_writeInstToCache; - hx_load_hit; + hx_ifetch_hit; s_deallocateTBE; o_popIncomingResponseQueue; kd_wakeUpDependents; @@ -720,7 +738,7 @@ machine(L0Cache, "MESI Directory L0 Cache") transition(Inst_IS, Data_Exclusive, E) { u_writeInstToCache; - hx_load_hit; + hx_ifetch_hit; s_deallocateTBE; o_popIncomingResponseQueue; kd_wakeUpDependents; diff --git a/src/mem/protocol/MESI_Two_Level-L1cache.sm b/src/mem/protocol/MESI_Two_Level-L1cache.sm index 8033e5983..b9be4663f 100644 --- a/src/mem/protocol/MESI_Two_Level-L1cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L1cache.sm @@ -810,36 +810,47 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") sequencer.invalidateSC(address); } - action(h_load_hit, "h", - desc="If not prefetch, notify sequencer the load completed.") + action(h_load_hit, "hd", + desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } - action(hx_load_hit, "hx", - desc="If not prefetch, notify sequencer the load completed.") + action(h_ifetch_hit, "hi", desc="Notify sequencer the instruction fetch completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk); + } + + action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") + { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, true); } - action(hh_store_hit, "\h", - desc="If not prefetch, notify sequencer that store completed.") + action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk); cache_entry.Dirty := true; } - action(hhx_store_hit, "\hx", - desc="If not prefetch, notify sequencer that store completed.") + action(hhx_store_hit, "\hx", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true); cache_entry.Dirty := true; } @@ -1081,7 +1092,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") } transition({S,E,M}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm index f3b1600f9..334106615 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -352,6 +352,7 @@ machine(L1Cache, "MI Example L1 Cache") action(r_load_hit, "r", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, false); } @@ -359,6 +360,7 @@ machine(L1Cache, "MI Example L1 Cache") peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender)); } @@ -367,6 +369,7 @@ machine(L1Cache, "MI Example L1 Cache") action(s_store_hit, "s", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, false); } @@ -374,6 +377,7 @@ machine(L1Cache, "MI Example L1 Cache") peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); DPRINTF(RubySlicc,"%s\n", cache_entry.DataBlk); + cacheMemory.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender)); } diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm index 6c5d3a20f..2ef80efd2 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm @@ -635,21 +635,32 @@ machine(L1Cache, "Directory protocol") } } - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk); + } + + action(h_ifetch_hit, "hi", desc="Notify the sequencer about ifetch completion.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk); } action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, true); } action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk); cache_entry.Dirty := true; } @@ -657,6 +668,8 @@ machine(L1Cache, "Directory protocol") action(xx_store_hit, "\xx", desc="Notify sequencer that store completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true); cache_entry.Dirty := true; } @@ -964,7 +977,7 @@ machine(L1Cache, "Directory protocol") } transition({S, SM, O, OM, MM, MM_W, M, M_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index c5a7cd940..230adfc4b 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -1282,12 +1282,22 @@ machine(L1Cache, "Token protocol") } } + action(h_load_hit, "hd", desc="Notify sequencer the load completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", + address, cache_entry.DataBlk); - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + L1Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk, false, + MachineType:L1Cache); + } + + action(h_ifetch_hit, "hi", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache); } @@ -1297,6 +1307,8 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); peek(responseNetwork_in, ResponseMsg) { + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, isExternalHit(address, in_msg.Sender), machineIDToMachineType(in_msg.Sender)); @@ -1308,6 +1320,7 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, false, MachineType:L1Cache); cache_entry.Dirty := true; @@ -1319,6 +1332,8 @@ machine(L1Cache, "Token protocol") DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", address, cache_entry.DataBlk); peek(responseNetwork_in, ResponseMsg) { + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, isExternalHit(address, in_msg.Sender), machineIDToMachineType(in_msg.Sender)); @@ -1700,7 +1715,7 @@ machine(L1Cache, "Token protocol") } transition({S, SM, S_L, SM_L}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1782,7 +1797,7 @@ machine(L1Cache, "Token protocol") // Transitions from Owned transition({O, OM}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1872,7 +1887,7 @@ machine(L1Cache, "Token protocol") // Transitions from Modified transition({MM, MM_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } @@ -1947,7 +1962,7 @@ machine(L1Cache, "Token protocol") // Transitions from Dirty Exclusive transition({M, M_W}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileInstHit; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 303bf1784..88b7308ed 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -853,9 +853,18 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } } - action(h_load_hit, "h", desc="Notify sequencer the load completed.") { + action(h_load_hit, "hd", desc="Notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Dcache.setMRU(cache_entry); + sequencer.readCallback(address, cache_entry.DataBlk, false, + testAndClearLocalHit(cache_entry)); + } + + action(h_ifetch_hit, "hi", desc="Notify sequencer the ifetch completed.") { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + L1Icache.setMRU(cache_entry); sequencer.readCallback(address, cache_entry.DataBlk, false, testAndClearLocalHit(cache_entry)); } @@ -865,7 +874,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(responseToCache_in, ResponseMsg) { - + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.readCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime, tbe.ForwardRequestTime, tbe.FirstResponseTime); @@ -876,6 +886,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(mandatoryQueue_in, RubyRequest) { + L1Dcache.setMRU(cache_entry); sequencer.writeCallback(address, cache_entry.DataBlk, false, testAndClearLocalHit(cache_entry)); @@ -897,7 +908,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); peek(responseToCache_in, ResponseMsg) { - + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(in_msg.Sender), tbe.InitialRequestTime, tbe.ForwardRequestTime, tbe.FirstResponseTime); @@ -910,7 +922,8 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") assert(is_valid(cache_entry)); assert(is_valid(tbe)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); - + L1Icache.setMRU(address); + L1Dcache.setMRU(address); sequencer.writeCallback(address, cache_entry.DataBlk, true, machineIDToMachineType(tbe.LastResponder), tbe.InitialRequestTime, tbe.ForwardRequestTime, tbe.FirstResponseTime); @@ -1504,7 +1517,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition({S, SM, ISM}, Ifetch) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1518,7 +1531,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(SR, Ifetch, S) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1566,7 +1579,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition({O, OM, SS, MM_W, M_W}, {Ifetch}) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1580,7 +1593,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(OR, Ifetch, O) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1631,7 +1644,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") // Transitions from Modified transition({MM, M}, {Ifetch}) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstHit; k_popMandatoryQueue; } @@ -1657,7 +1670,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(MMR, Ifetch, MM) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; @@ -1738,7 +1751,7 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol") } transition(MR, Ifetch, M) { - h_load_hit; + h_ifetch_hit; uu_profileL1InstMiss; uu_profileL2Hit; k_popMandatoryQueue; diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index d032adfd8..f464b3c7d 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -156,6 +156,7 @@ structure (CacheMemory, external = "yes") { Cycles getTagLatency(); Cycles getDataLatency(); void setMRU(Addr); + void setMRU(AbstractCacheEntry); void recordRequestType(CacheRequestType, Addr); bool checkResourceAvailable(CacheResourceType, Addr); |