diff options
author | Brad Beckmann <Brad.Beckmann@amd.com> | 2009-11-18 16:34:33 -0800 |
---|---|---|
committer | Brad Beckmann <Brad.Beckmann@amd.com> | 2009-11-18 16:34:33 -0800 |
commit | 5d8a669539a142ece820cf0c82722ea1c755d7cd (patch) | |
tree | b17fb03643674b83785859378296ed4690e3d715 /src/mem/ruby | |
parent | c6182199c54a874315a97338879d5bfaf3895a6f (diff) | |
download | gem5-5d8a669539a142ece820cf0c82722ea1c755d7cd.tar.xz |
Resurrection of the CMP token protocol to GEM5
Diffstat (limited to 'src/mem/ruby')
-rw-r--r-- | src/mem/ruby/SConscript | 1 | ||||
-rw-r--r-- | src/mem/ruby/common/NetDest.cc | 5 | ||||
-rw-r--r-- | src/mem/ruby/common/NetDest.hh | 2 | ||||
-rw-r--r-- | src/mem/ruby/config/MOESI_CMP_token.rb | 92 | ||||
-rw-r--r-- | src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb | 55 | ||||
-rw-r--r-- | src/mem/ruby/config/cfg.rb | 1 | ||||
-rw-r--r-- | src/mem/ruby/config/defaults.rb | 27 | ||||
-rw-r--r-- | src/mem/ruby/system/PersistentTable.cc | 82 | ||||
-rw-r--r-- | src/mem/ruby/system/PersistentTable.hh | 40 | ||||
-rw-r--r-- | src/mem/ruby/system/SConscript | 1 |
10 files changed, 246 insertions, 60 deletions
diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript index 0c8423c85..3559f042f 100644 --- a/src/mem/ruby/SConscript +++ b/src/mem/ruby/SConscript @@ -114,6 +114,7 @@ MakeInclude('system/MachineID.hh') MakeInclude('system/MemoryControl.hh') MakeInclude('system/NodeID.hh') MakeInclude('system/PerfectCacheMemory.hh') +MakeInclude('system/PersistentTable.hh') MakeInclude('system/Sequencer.hh') MakeInclude('system/TBETable.hh') MakeInclude('system/TimerTable.hh') diff --git a/src/mem/ruby/common/NetDest.cc b/src/mem/ruby/common/NetDest.cc index 32771235f..35bb4ec43 100644 --- a/src/mem/ruby/common/NetDest.cc +++ b/src/mem/ruby/common/NetDest.cc @@ -133,13 +133,14 @@ NodeID NetDest::elementAt(MachineID index) { return m_bits[vecIndex(index)].elementAt(bitIndex(index.num)); } -NodeID NetDest::smallestElement() const +MachineID NetDest::smallestElement() const { assert(count() > 0); for (int i=0; i<m_bits.size(); i++) { for (int j=0; j<m_bits[i].getSize(); j++) { if (m_bits[i].isElement(j)) { - return j; + MachineID mach = {MachineType_from_base_level(i), j}; + return mach; } } } diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh index 7301409ce..071106623 100644 --- a/src/mem/ruby/common/NetDest.hh +++ b/src/mem/ruby/common/NetDest.hh @@ -96,7 +96,7 @@ public: //For Princeton Network Vector<NodeID> getAllDest(); - NodeID smallestElement() const; + MachineID smallestElement() const; MachineID smallestElement(MachineType machine) const; void setSize(); diff --git a/src/mem/ruby/config/MOESI_CMP_token.rb b/src/mem/ruby/config/MOESI_CMP_token.rb new file mode 100644 index 000000000..ba963dc06 --- /dev/null +++ b/src/mem/ruby/config/MOESI_CMP_token.rb @@ -0,0 +1,92 @@ + +require "cfg.rb" +require "util.rb" + + +class MOESI_CMP_token_L1CacheController < L1CacheController + attr :icache, :dcache + attr :num_l2_controllers + attr :n_tokens + def initialize(obj_name, mach_type, icache, dcache, sequencer, num_l2_controllers, n_tokens) + super(obj_name, mach_type, [icache, dcache], sequencer) + @icache = icache + @dcache = dcache + @num_l2_controllers = num_l2_controllers + @n_tokens = n_tokens + end + def argv() + num_select_bits = log_int(num_l2_controllers) + num_block_bits = log_int(RubySystem.block_size_bytes) + + l2_select_low_bit = num_block_bits + + vec = super() + vec += " icache " + @icache.obj_name + vec += " dcache " + @dcache.obj_name + vec += " l1_request_latency " + l1_request_latency.to_s + vec += " l1_response_latency " + l1_response_latency.to_s + vec += " l2_select_low_bit " + l2_select_low_bit.to_s + vec += " l2_select_num_bits " + num_select_bits.to_s + vec += " N_tokens " + n_tokens.to_s + vec += " retry_threshold " + retry_threshold.to_s + vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s + vec += " dynamic_timeout_enabled " + dynamic_timeout_enabled.to_s + + return vec + end +end + +class MOESI_CMP_token_L2CacheController < CacheController + attr :cache + attr :n_tokens + def initialize(obj_name, mach_type, cache, n_tokens) + super(obj_name, mach_type, [cache]) + @cache = cache + @n_tokens = n_tokens + end + def argv() + vec = super() + vec += " cache " + @cache.obj_name + vec += " l2_request_latency " + l2_request_latency.to_s + vec += " l2_response_latency " + l2_response_latency.to_s + vec += " N_tokens " + n_tokens.to_s + vec += " filtering_enabled " + filtering_enabled.to_s + return vec + end +end + + +class MOESI_CMP_token_DirectoryController < DirectoryController + attr :num_l2_controllers + def initialize(obj_name, mach_type, directory, memory_control, num_l2_controllers) + super(obj_name, mach_type, directory, memory_control) + @num_l2_controllers = num_l2_controllers + end + def argv() + num_select_bits = log_int(num_l2_controllers) + num_block_bits = log_int(RubySystem.block_size_bytes) + + l2_select_low_bit = num_block_bits + + vec = super() + vec += " directory_latency "+directory_latency.to_s + vec += " l2_select_low_bit " + l2_select_low_bit.to_s + vec += " l2_select_num_bits " + num_select_bits.to_s + vec += " distributed_persistent "+distributed_persistent.to_s + vec += " fixed_timeout_latency " + fixed_timeout_latency.to_s + return vec + end + +end + +class MOESI_CMP_token_DMAController < DMAController + def initialize(obj_name, mach_type, dma_sequencer) + super(obj_name, mach_type, dma_sequencer) + end + def argv() + vec = super + vec += " request_latency "+request_latency.to_s + vec += " response_latency "+response_latency.to_s + return vec + end +end diff --git a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb index 83020742e..566055f74 100644 --- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb +++ b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb @@ -12,13 +12,13 @@ RubySystem.reset # default values num_cores = 2 -l1_icache_size_kb = 32 +l1_icache_size_bytes = 32768 l1_icache_assoc = 8 l1_icache_latency = 1 -l1_dcache_size_kb = 32 +l1_dcache_size_bytes = 32768 l1_dcache_assoc = 8 l1_dcache_latency = 1 -l2_cache_size_kb = 2048 # total size (sum of all banks) +l2_cache_size_bytes = 2048 # total size (sum of all banks) l2_cache_assoc = 16 l2_cache_latency = 12 num_l2_banks = num_cores @@ -26,7 +26,7 @@ num_memories = 1 memory_size_mb = 1024 num_dma = 1 -protocol = "MESI_CMP_directory" +protocol = "MOESI_CMP_token" # check for overrides @@ -43,9 +43,20 @@ for i in 0..$*.size-1 do elsif $*[i] == "-s" memory_size_mb = $*[i+1].to_i i = i + 1 + elsif $*[i] == "-C" + l1_dcache_size_bytes = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-A" + l1_dcache_assoc = $*[i+1].to_i + i = i + 1 + elsif $*[i] == "-D" + num_dma = $*[i+1].to_i + i = i + 1 end end +n_tokens = num_cores + 1 + net_ports = Array.new iface_ports = Array.new @@ -54,10 +65,19 @@ iface_ports = Array.new require protocol+".rb" num_cores.times { |n| - icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_kb, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU") - dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_kb, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU") + icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_bytes, l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU") + dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_bytes, l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU") sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache) iface_ports << sequencer + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_L1CacheController.new("L1CacheController_"+n.to_s, + "L1Cache", + icache, dcache, + sequencer, + num_l2_banks, + n_tokens) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_L1CacheController.new("L1CacheController_"+n.to_s, "L1Cache", @@ -75,7 +95,14 @@ num_cores.times { |n| end } num_l2_banks.times { |n| - cache = SetAssociativeCache.new("l2u_"+n.to_s, l2_cache_size_kb/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU") + cache = SetAssociativeCache.new("l2u_"+n.to_s, l2_cache_size_bytes/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU") + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_L2CacheController.new("L2CacheController_"+n.to_s, + "L2Cache", + cache, + n_tokens) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s, "L2Cache", @@ -93,6 +120,14 @@ num_l2_banks.times { |n| num_memories.times { |n| directory = DirectoryMemory.new("DirectoryMemory_"+n.to_s, memory_size_mb/num_memories) memory_control = MemoryControl.new("MemoryControl_"+n.to_s) + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_DirectoryController.new("DirectoryController_"+n.to_s, + "Directory", + directory, + memory_control, + num_l2_banks) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_DirectoryController.new("DirectoryController_"+n.to_s, "Directory", @@ -111,6 +146,12 @@ num_memories.times { |n| num_dma.times { |n| dma_sequencer = DMASequencer.new("DMASequencer_"+n.to_s) iface_ports << dma_sequencer + if protocol == "MOESI_CMP_token" + net_ports << MOESI_CMP_token_DMAController.new("DMAController_"+n.to_s, + "DMA", + dma_sequencer) + end + if protocol == "MOESI_CMP_directory" net_ports << MOESI_CMP_directory_DMAController.new("DMAController_"+n.to_s, "DMA", diff --git a/src/mem/ruby/config/cfg.rb b/src/mem/ruby/config/cfg.rb index f2564e1d3..c470ca92f 100644 --- a/src/mem/ruby/config/cfg.rb +++ b/src/mem/ruby/config/cfg.rb @@ -538,7 +538,6 @@ class MemoryControl < LibRubyObject end end - class Sequencer < IfacePort def cppClassName() diff --git a/src/mem/ruby/config/defaults.rb b/src/mem/ruby/config/defaults.rb index bb054ec4e..f338f4e3f 100644 --- a/src/mem/ruby/config/defaults.rb +++ b/src/mem/ruby/config/defaults.rb @@ -167,6 +167,33 @@ class MOESI_CMP_directory_DMAController < DMAController default_param :response_latency, Integer, 6 end +## MOESI_CMP_token protocol + +class MOESI_CMP_token_L1CacheController < L1CacheController + default_param :l1_request_latency, Integer, 2 + default_param :l1_response_latency, Integer, 2 + default_param :retry_threshold, Integer, 1 + default_param :fixed_timeout_latency, Integer, 300 + default_param :dynamic_timeout_enabled, Boolean, true +end + +class MOESI_CMP_token_L2CacheController < CacheController + default_param :l2_request_latency, Integer, 2 + default_param :l2_response_latency, Integer, 2 + default_param :filtering_enabled, Boolean, true +end + +class MOESI_CMP_token_DirectoryController < DirectoryController + default_param :directory_latency, Integer, 6 + default_param :distributed_persistent, Boolean, true + default_param :fixed_timeout_latency, Integer, 300 +end + +class MOESI_CMP_token_DMAController < DMAController + default_param :request_latency, Integer, 6 + default_param :response_latency, Integer, 6 +end + ## MOESI_hammer protocol class MOESI_hammer_CacheController < L1CacheController diff --git a/src/mem/ruby/system/PersistentTable.cc b/src/mem/ruby/system/PersistentTable.cc index 1e056f6e5..58b67ea60 100644 --- a/src/mem/ruby/system/PersistentTable.cc +++ b/src/mem/ruby/system/PersistentTable.cc @@ -27,44 +27,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "PersistentTable.hh" -#include "NetDest.h" -#include "Map.h" -#include "Address.h" -#include "AbstractChip.h" -#include "util.h" +#include "mem/ruby/system/PersistentTable.hh" +#include "mem/gems_common/util.hh" // randomize so that handoffs are not locality-aware // int persistent_randomize[] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}; // int persistent_randomize[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -class PersistentTableEntry { -public: - NetDest m_starving; - NetDest m_marked; - NetDest m_request_to_write; -}; - -PersistentTable::PersistentTable(AbstractChip* chip_ptr, int version) +PersistentTable::PersistentTable() { - m_chip_ptr = chip_ptr; m_map_ptr = new Map<Address, PersistentTableEntry>; - m_version = version; } PersistentTable::~PersistentTable() { delete m_map_ptr; m_map_ptr = NULL; - m_chip_ptr = NULL; } -void PersistentTable::persistentRequestLock(const Address& address, MachineID locker, AccessType type) +void PersistentTable::persistentRequestLock(const Address& address, + MachineID locker, + AccessType type) { // if (locker == m_chip_ptr->getID() ) - // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker << " requesting lock for " << address << endl; + // cout << "Chip " << m_chip_ptr->getID() << ": " << llocker + // << " requesting lock for " << address << endl; // MachineID locker = (MachineID) persistent_randomize[llocker]; @@ -79,7 +68,11 @@ void PersistentTable::persistentRequestLock(const Address& address, MachineID lo m_map_ptr->add(address, entry); } else { PersistentTableEntry& entry = m_map_ptr->lookup(address); - assert(!(entry.m_starving.isElement(locker))); // Make sure we're not already in the locked set + + // + // Make sure we're not already in the locked set + // + assert(!(entry.m_starving.isElement(locker))); entry.m_starving.add(locker); if (type == AccessType_Write) { @@ -89,17 +82,23 @@ void PersistentTable::persistentRequestLock(const Address& address, MachineID lo } } -void PersistentTable::persistentRequestUnlock(const Address& address, MachineID unlocker) +void PersistentTable::persistentRequestUnlock(const Address& address, + MachineID unlocker) { // if (unlocker == m_chip_ptr->getID() ) - // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker << " requesting unlock for " << address << endl; + // cout << "Chip " << m_chip_ptr->getID() << ": " << uunlocker + // << " requesting unlock for " << address << endl; // MachineID unlocker = (MachineID) persistent_randomize[uunlocker]; assert(address == line_address(address)); assert(m_map_ptr->exist(address)); PersistentTableEntry& entry = m_map_ptr->lookup(address); - assert(entry.m_starving.isElement(unlocker)); // Make sure we're in the locked set + + // + // Make sure we're in the locked set + // + assert(entry.m_starving.isElement(unlocker)); assert(entry.m_marked.isSubset(entry.m_starving)); entry.m_starving.remove(unlocker); entry.m_marked.remove(unlocker); @@ -113,13 +112,20 @@ void PersistentTable::persistentRequestUnlock(const Address& address, MachineID } } -bool PersistentTable::okToIssueStarving(const Address& address) const +bool PersistentTable::okToIssueStarving(const Address& address, + MachineID machId) const { assert(address == line_address(address)); if (!m_map_ptr->exist(address)) { - return true; // No entry present - } else if (m_map_ptr->lookup(address).m_starving.isElement( (MachineID) {MachineType_L1Cache, m_version})) { - return false; // We can't issue another lockdown until are previous unlock has occurred + // + // No entry present + // + return true; + } else if (m_map_ptr->lookup(address).m_starving.isElement(machId)) { + // + // We can't issue another lockdown until are previous unlock has occurred + // + return false; } else { return (m_map_ptr->lookup(address).m_marked.isEmpty()); } @@ -130,9 +136,7 @@ MachineID PersistentTable::findSmallest(const Address& address) const assert(address == line_address(address)); assert(m_map_ptr->exist(address)); const PersistentTableEntry& entry = m_map_ptr->lookup(address); - // cout << "Node " << m_chip_ptr->getID() << " returning " << persistent_randomize[entry.m_starving.smallestElement()] << " for findSmallest(" << address << ")" << endl; - // return (MachineID) persistent_randomize[entry.m_starving.smallestElement()]; - return (MachineID) { MachineType_L1Cache, entry.m_starving.smallestElement() }; + return entry.m_starving.smallestElement(); } AccessType PersistentTable::typeOfSmallest(const Address& address) const @@ -140,7 +144,7 @@ AccessType PersistentTable::typeOfSmallest(const Address& address) const assert(address == line_address(address)); assert(m_map_ptr->exist(address)); const PersistentTableEntry& entry = m_map_ptr->lookup(address); - if (entry.m_request_to_write.isElement((MachineID) {MachineType_L1Cache, entry.m_starving.smallestElement()})) { + if (entry.m_request_to_write.isElement(entry.m_starving.smallestElement())) { return AccessType_Write; } else { return AccessType_Read; @@ -152,8 +156,16 @@ void PersistentTable::markEntries(const Address& address) assert(address == line_address(address)); if (m_map_ptr->exist(address)) { PersistentTableEntry& entry = m_map_ptr->lookup(address); - assert(entry.m_marked.isEmpty()); // None should be marked - entry.m_marked = entry.m_starving; // Mark all the nodes currently in the table + + // + // None should be marked + // + assert(entry.m_marked.isEmpty()); + + // + // Mark all the nodes currently in the table + // + entry.m_marked = entry.m_starving; } } @@ -177,7 +189,6 @@ int PersistentTable::countStarvingForAddress(const Address& address) const int PersistentTable::countReadStarvingForAddress(const Address& address) const { - int count = 0; if (m_map_ptr->exist(address)) { PersistentTableEntry& entry = m_map_ptr->lookup(address); return (entry.m_starving.count() - entry.m_request_to_write.count()); @@ -187,4 +198,7 @@ int PersistentTable::countReadStarvingForAddress(const Address& address) const } } +void PersistentTable::print(ostream& out) const +{ +} diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh index ab000843d..8cbb48817 100644 --- a/src/mem/ruby/system/PersistentTable.hh +++ b/src/mem/ruby/system/PersistentTable.hh @@ -30,20 +30,26 @@ #ifndef PersistentTable_H #define PersistentTable_H -#include "Global.h" -#include "MachineID.h" -#include "AccessType.h" +#include "mem/ruby/common/Global.hh" +#include "mem/gems_common/Map.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/system/MachineID.hh" +#include "mem/protocol/AccessType.hh" +#include "mem/ruby/common/NetDest.hh" -class AbstractChip; +class PersistentTableEntry { +public: + void print(ostream& out) const {} -template <class KEY_TYPE, class VALUE_TYPE> class Map; -class Address; -class PersistentTableEntry; + NetDest m_starving; + NetDest m_marked; + NetDest m_request_to_write; +}; class PersistentTable { public: // Constructors - PersistentTable(AbstractChip* chip_ptr, int version); + PersistentTable(); // Destructor ~PersistentTable(); @@ -51,7 +57,7 @@ public: // Public Methods void persistentRequestLock(const Address& address, MachineID locker, AccessType type); void persistentRequestUnlock(const Address& address, MachineID unlocker); - bool okToIssueStarving(const Address& address) const; + bool okToIssueStarving(const Address& address, MachineID machID) const; MachineID findSmallest(const Address& address) const; AccessType typeOfSmallest(const Address& address) const; void markEntries(const Address& address); @@ -71,17 +77,12 @@ private: // Data Members (m_prefix) Map<Address, PersistentTableEntry>* m_map_ptr; - AbstractChip* m_chip_ptr; - int m_version; }; -// Output operator declaration -ostream& operator<<(ostream& out, const PersistentTable& obj); - // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const PersistentTable& obj) { obj.print(out); @@ -89,4 +90,13 @@ ostream& operator<<(ostream& out, const PersistentTable& obj) return out; } +// Output operator definition +extern inline +ostream& operator<<(ostream& out, const PersistentTableEntry& obj) +{ + obj.print(out); + out << flush; + return out; +} + #endif //PersistentTable_H diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript index 496fce2fd..4ca1af114 100644 --- a/src/mem/ruby/system/SConscript +++ b/src/mem/ruby/system/SConscript @@ -38,6 +38,7 @@ Source('DirectoryMemory.cc') Source('CacheMemory.cc') Source('MemoryControl.cc') Source('MemoryNode.cc') +Source('PersistentTable.cc') Source('RubyPort.cc') Source('Sequencer.cc', Werror=False) Source('System.cc') |