changeset 9adf5b0ccc79 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=9adf5b0ccc79
description:
ruby: Ruby support for sparse memory
The patch includes direct support for the MI example protocol.
diffstat:
12 files changed, 658 insertions(+), 50 deletions(-)
configs/common/Options.py | 6
configs/ruby/MI_example.py | 4
configs/ruby/Ruby.py | 6
src/mem/protocol/MI_example-dir.sm | 18 -
src/mem/ruby/system/DirectoryMemory.cc | 108 +++++---
src/mem/ruby/system/DirectoryMemory.hh | 12
src/mem/ruby/system/DirectoryMemory.py | 2
src/mem/ruby/system/SConscript | 1
src/mem/ruby/system/SparseMemory.cc | 425 ++++++++++++++++++++++++++++++++
src/mem/ruby/system/SparseMemory.hh | 114 ++++++++
src/mem/ruby/system/System.cc | 11
src/mem/slicc/symbols/StateMachine.py | 1
diffs (truncated from 941 to 300 lines):
diff -r 30883414ad10 -r 9adf5b0ccc79 configs/common/Options.py
--- a/configs/common/Options.py Sun Mar 21 21:22:21 2010 -0700
+++ b/configs/common/Options.py Sun Mar 21 21:22:21 2010 -0700
@@ -43,7 +43,11 @@
help="the number of rows in the mesh topology")
parser.add_option("--garnet-network", type="string", default=none,
help="'fixed'|'flexible'")
-
+
+# ruby sparse memory options
+parser.add_option("--use-map", action="store_true", default=False)
+parser.add_option("--map-levels", type="int", default=4)
+
# Run duration options
parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick,
metavar="T",
diff -r 30883414ad10 -r 9adf5b0ccc79 configs/ruby/MI_example.py
--- a/configs/ruby/MI_example.py Sun Mar 21 21:22:21 2010 -0700
+++ b/configs/ruby/MI_example.py Sun Mar 21 21:22:21 2010 -0700
@@ -105,7 +105,9 @@
dir_cntrl = Directory_Controller(version = i,
directory = \
RubyDirectoryMemory(version = i,
- size = dir_size),
+ size = dir_size,
+ use_map = options.use_map,
+ map_levels =
options.map_levels),
memBuffer = mem_cntrl)
dir_cntrl_nodes.append(dir_cntrl)
diff -r 30883414ad10 -r 9adf5b0ccc79 configs/ruby/Ruby.py
--- a/configs/ruby/Ruby.py Sun Mar 21 21:22:21 2010 -0700
+++ b/configs/ruby/Ruby.py Sun Mar 21 21:22:21 2010 -0700
@@ -78,8 +78,10 @@
network = SimpleNetwork(topology = net_topology)
#
- # determine the total memory size of the ruby system and verify it is equal
- # to physmem
+ # Determine the total memory size of the ruby system and verify it is equal
+ # to physmem. However, if Ruby memory is using sparse memory in SE
+ # mode, then the system should not back-up the memory state with
+ # the Memory Vector and thus the memory size bytes should stay at 0.
#
total_mem_size = MemorySize('0B')
for dir_cntrl in dir_cntrls:
diff -r 30883414ad10 -r 9adf5b0ccc79 src/mem/protocol/MI_example-dir.sm
--- a/src/mem/protocol/MI_example-dir.sm Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/protocol/MI_example-dir.sm Sun Mar 21 21:22:21 2010 -0700
@@ -98,15 +98,18 @@
if (directory.isPresent(addr)) {
- if (state == State:I) {
- assert(getDirectoryEntry(addr).Owner.count() == 0);
- assert(getDirectoryEntry(addr).Sharers.count() == 0);
- } else if (state == State:M) {
+ if (state == State:M) {
assert(getDirectoryEntry(addr).Owner.count() == 1);
assert(getDirectoryEntry(addr).Sharers.count() == 0);
}
getDirectoryEntry(addr).DirectoryState := state;
+
+ if (state == State:I) {
+ assert(getDirectoryEntry(addr).Owner.count() == 0);
+ assert(getDirectoryEntry(addr).Sharers.count() == 0);
+ directory.invalidateBlock(addr);
+ }
}
}
@@ -264,10 +267,6 @@
}
}
- action(d_deallocateDirectory, "\d", desc="Deallocate Directory Entry") {
- directory.invalidateBlock(address);
- }
-
action(e_ownerIsRequestor, "e", desc="The owner is now the requestor") {
peek(requestQueue_in, RequestMsg) {
getDirectoryEntry(address).Owner.clear();
@@ -527,7 +526,6 @@
transition(M_DRDI, Memory_Ack, I) {
l_sendWriteBackAck;
w_deallocateTBE;
- d_deallocateDirectory;
l_popMemQueue;
}
@@ -550,7 +548,6 @@
l_sendWriteBackAck;
da_sendDMAAck;
w_deallocateTBE;
- d_deallocateDirectory;
l_popMemQueue;
}
@@ -572,7 +569,6 @@
w_writeDataToMemoryFromTBE;
l_sendWriteBackAck;
w_deallocateTBE;
- d_deallocateDirectory;
l_popMemQueue;
}
diff -r 30883414ad10 -r 9adf5b0ccc79 src/mem/ruby/system/DirectoryMemory.cc
--- a/src/mem/ruby/system/DirectoryMemory.cc Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/ruby/system/DirectoryMemory.cc Sun Mar 21 21:22:21 2010 -0700
@@ -51,14 +51,24 @@
m_version = p->version;
m_size_bytes = p->size;
m_size_bits = log_int(m_size_bytes);
+ m_num_entries = 0;
+ m_use_map = p->use_map;
+ m_map_levels = p->map_levels;
}
void DirectoryMemory::init()
{
m_num_entries = m_size_bytes / RubySystem::getBlockSizeBytes();
- m_entries = new Directory_Entry*[m_num_entries];
- for (int i=0; i < m_num_entries; i++)
- m_entries[i] = NULL;
+
+ if (m_use_map) {
+ int entry_bits = log_int(m_num_entries);
+ assert(entry_bits >= m_map_levels);
+ m_sparseMemory = new SparseMemory(entry_bits, m_map_levels);
+ } else {
+ m_entries = new Directory_Entry*[m_num_entries];
+ for (int i=0; i < m_num_entries; i++)
+ m_entries[i] = NULL;
+ }
m_ram = g_system_ptr->getMemoryVector();
@@ -70,13 +80,15 @@
DirectoryMemory::~DirectoryMemory()
{
// free up all the directory entries
- for (uint64 i=0;i<m_num_entries;i++) {
- if (m_entries[i] != NULL) {
- delete m_entries[i];
- }
- }
if (m_entries != NULL) {
- delete [] m_entries;
+ for (uint64 i = 0; i < m_num_entries; i++) {
+ if (m_entries[i] != NULL) {
+ delete m_entries[i];
+ }
+ }
+ delete [] m_entries;
+ } else if (m_use_map) {
+ delete m_sparseMemory;
}
}
@@ -102,14 +114,14 @@
<< "-" << RubySystem::getBlockSizeBits() << endl;
}
out << " total memory size bytes: " << m_total_size_bytes << endl;
- out << " total memory size bits: " << log_int(m_total_size_bytes) << endl;
+ out << " total memory bits: " << log_int(m_total_size_bytes) << endl;
}
-int DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
+uint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
{
if (m_num_directories_bits == 0) return 0;
- int ret = address.bitSelect(RubySystem::getBlockSizeBits(),
+ uint64 ret = address.bitSelect(RubySystem::getBlockSizeBits(),
RubySystem::getBlockSizeBits()+m_num_directories_bits-1);
return ret;
}
@@ -121,9 +133,10 @@
return ret;
}
-int DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
+uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
{
- int ret = address.getAddress() >> (RubySystem::getBlockSizeBits() +
m_num_directories_bits);
+ uint64 ret = address.getAddress()
+ >> (RubySystem::getBlockSizeBits() + m_num_directories_bits);
return ret;
}
@@ -131,13 +144,32 @@
{
assert(isPresent(address));
Directory_Entry* entry;
- int idx = mapAddressToLocalIdx(address);
- entry = m_entries[idx];
- if (entry == NULL) {
- entry = new Directory_Entry;
- entry->getDataBlk().assign(m_ram->getBlockPtr(address));
- m_entries[idx] = entry;
+ uint64 idx;
+ DEBUG_EXPR(CACHE_COMP, HighPrio, address);
+
+ if (m_use_map) {
+ if (m_sparseMemory->exist(address)) {
+ entry = m_sparseMemory->lookup(address);
+ assert(entry != NULL);
+ } else {
+ //
+ // Note: SparseMemory internally creates a new Directory Entry
+ //
+ m_sparseMemory->add(address);
+ entry = m_sparseMemory->lookup(address);
+ }
+ } else {
+ idx = mapAddressToLocalIdx(address);
+ assert(idx < m_num_entries);
+ entry = m_entries[idx];
+
+ if (entry == NULL) {
+ entry = new Directory_Entry();
+ entry->getDataBlk().assign(m_ram->getBlockPtr(address));
+ m_entries[idx] = entry;
+ }
}
+
return (*entry);
}
/*
@@ -169,20 +201,29 @@
void DirectoryMemory::invalidateBlock(PhysAddress address)
{
+
+ if (m_use_map) {
+ assert(m_sparseMemory->exist(address));
+ m_sparseMemory->remove(address);
+ }
/*
- assert(isPresent(address));
+ else {
+ assert(isPresent(address));
+
+ Index index = address.memoryModuleIndex();
+
+ if (index < 0 || index > m_size) {
+ ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
+ }
- Index index = address.memoryModuleIndex();
-
- if (index < 0 || index > m_size) {
- ERROR_MSG("Directory Memory Assertion: accessing memory out of range.");
- }
-
- if(m_entries[index] != NULL){
- delete m_entries[index];
- m_entries[index] = NULL;
+ if(m_entries[index] != NULL){
+ delete m_entries[index];
+ m_entries[index] = NULL;
+ }
}
*/
+
+
}
void DirectoryMemory::print(ostream& out) const
@@ -190,6 +231,13 @@
}
+void DirectoryMemory::printStats(ostream& out) const
+{
+ if (m_use_map) {
+ m_sparseMemory->printStats(out);
+ }
+}
+
DirectoryMemory *
RubyDirectoryMemoryParams::create()
{
diff -r 30883414ad10 -r 9adf5b0ccc79 src/mem/ruby/system/DirectoryMemory.hh
--- a/src/mem/ruby/system/DirectoryMemory.hh Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/ruby/system/DirectoryMemory.hh Sun Mar 21 21:22:21 2010 -0700
@@ -45,6 +45,7 @@
#include "mem/protocol/Directory_Entry.hh"
#include "sim/sim_object.hh"
#include "params/RubyDirectoryMemory.hh"
+#include "mem/ruby/system/SparseMemory.hh"
class DirectoryMemory : public SimObject {
public:
@@ -57,9 +58,10 @@
// Destructor
~DirectoryMemory();
- int mapAddressToLocalIdx(PhysAddress address);
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev