ruby: Adds configurable bit selection for numa mapping
authorBrad Beckmann <Brad.Beckmann@amd.com>
Mon, 22 Mar 2010 04:22:21 +0000 (21:22 -0700)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Mon, 22 Mar 2010 04:22:21 +0000 (21:22 -0700)
configs/common/Options.py
src/mem/ruby/common/Address.hh
src/mem/ruby/system/DirectoryMemory.cc
src/mem/ruby/system/DirectoryMemory.hh
src/mem/ruby/system/DirectoryMemory.py

index b0153f45352fdeae6a6e70b91895f44c1f6ba1b7..e7ab0d86b8c6c0d626ee19b298bad288a02909bb 100644 (file)
@@ -43,6 +43,8 @@ parser.add_option("--mesh-rows", type="int", default=1,
                   help="the number of rows in the mesh topology")
 parser.add_option("--garnet-network", type="string", default=none,
                   help="'fixed'|'flexible'")
+parser.add_option("--numa-high-bit", type="int", default=none,
+                  help="high order address bit to use for numa mapping")
 
 # ruby sparse memory options
 parser.add_option("--use-map", action="store_true", default=False)
index 44dff7d832109d87a024cdea8357bbd5945699cf..7da5ed0fe982354fa6041262617bcbf27784d44d 100644 (file)
@@ -66,6 +66,7 @@ public:
   physical_address_t getAddress() const {return m_address;}
   // selects bits inclusive
   physical_address_t bitSelect(int small, int big) const;
+  physical_address_t bitRemove(int small, int big) const;
   physical_address_t maskLowOrderBits(int number) const;
   physical_address_t maskHighOrderBits(int number) const;
   physical_address_t shiftLowOrderBits(int number) const;
@@ -162,6 +163,35 @@ physical_address_t Address::bitSelect(int small, int big) const // rips bits inc
   }
 }
 
+// removes bits inclusive
+inline
+physical_address_t Address::bitRemove(int small, int big) const
+{
+    physical_address_t mask;
+    assert((unsigned)big >= (unsigned)small);
+    
+    if (small >= ADDRESS_WIDTH - 1) {
+        return m_address;
+    } else if (big >= ADDRESS_WIDTH - 1) {
+        mask = (physical_address_t)~0 >> small;
+        return (m_address & mask);
+    } else if (small == 0) {
+        mask = (physical_address_t)~0 << big;
+        return (m_address & mask);
+    } else {
+        mask = ~((physical_address_t)~0 << small);
+        physical_address_t lower_bits = m_address & mask;
+        mask = (physical_address_t)~0 << (big + 1);
+        physical_address_t higher_bits = m_address & mask;
+
+        //
+        // Shift the valid high bits over the removed section
+        //
+        higher_bits = higher_bits >> (big - small);
+        return (higher_bits | lower_bits);
+    }
+}
+
 inline
 physical_address_t Address::maskLowOrderBits(int number) const
 {
index 2c32eacdc5ca4baf2c0e03d33b272e4c463d0a11..d8037aec1ca94dadd49aacc9fbedb48b904fb043 100644 (file)
@@ -44,6 +44,7 @@
 int DirectoryMemory::m_num_directories = 0;
 int DirectoryMemory::m_num_directories_bits = 0;
 uint64_t DirectoryMemory::m_total_size_bytes = 0;
+int DirectoryMemory::m_numa_high_bit = 0;
 
 DirectoryMemory::DirectoryMemory(const Params *p)
     : SimObject(p)
@@ -54,6 +55,7 @@ DirectoryMemory::DirectoryMemory(const Params *p)
     m_num_entries = 0;
     m_use_map = p->use_map;
     m_map_levels = p->map_levels;
+    m_numa_high_bit = p->numa_high_bit;
 }
 
 void DirectoryMemory::init()
@@ -74,6 +76,11 @@ void DirectoryMemory::init()
   m_num_directories++;
   m_num_directories_bits = log_int(m_num_directories);
   m_total_size_bytes += m_size_bytes;
+
+  if (m_numa_high_bit == 0) {
+      m_numa_high_bit = RubySystem::getMemorySizeBits();
+  }
+  assert(m_numa_high_bit != 0);
 }
 
 DirectoryMemory::~DirectoryMemory()
@@ -109,8 +116,9 @@ void DirectoryMemory::printGlobalConfig(ostream & out)
   out << "  number of directory memories: " << m_num_directories << endl;
   if (m_num_directories > 1) {
     out << "  number of selection bits: " << m_num_directories_bits << endl;
-    out << "  selection bits: " << RubySystem::getBlockSizeBits()+m_num_directories_bits-1
-        << "-" << RubySystem::getBlockSizeBits() << endl;
+    out << "  selection bits: " << m_numa_high_bit
+        << "-" << m_numa_high_bit-m_num_directories_bits 
+        << endl;
   }
   out << "  total memory size bytes: " << m_total_size_bytes << endl;
   out << "  total memory bits: " << log_int(m_total_size_bytes) << endl;
@@ -120,8 +128,8 @@ void DirectoryMemory::printGlobalConfig(ostream & out)
 uint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
 {
   if (m_num_directories_bits == 0) return 0;
-  uint64 ret = address.bitSelect(RubySystem::getBlockSizeBits(),
-                              RubySystem::getBlockSizeBits()+m_num_directories_bits-1);
+  uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits,
+                                 m_numa_high_bit);
   return ret;
 }
 
@@ -134,9 +142,10 @@ bool DirectoryMemory::isPresent(PhysAddress address)
 
 uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
 {
-  uint64 ret = address.getAddress()
-      >> (RubySystem::getBlockSizeBits() + m_num_directories_bits);
-  return ret;
+    uint64 ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits,
+                                   m_numa_high_bit)
+        >> (RubySystem::getBlockSizeBits());
+    return ret;
 }
 
 Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
index 455329cd063516c3d537a6b1095811e2b3217668..8b23ced0283a5f484db3adb2aab2e9e181d927bc 100644 (file)
@@ -95,6 +95,7 @@ private:
   static int m_num_directories;
   static int m_num_directories_bits;
   static uint64_t m_total_size_bytes;
+  static int m_numa_high_bit;
 
   MemoryVector* m_ram;
   SparseMemory* m_sparseMemory;
index 9892f3135939ce28c9cc758a8ad5a7d7d6b9d72b..784ed628fe4bc44da9dac3bcd4476616675e984e 100644 (file)
@@ -38,3 +38,4 @@ class RubyDirectoryMemory(SimObject):
     size = Param.MemorySize("1GB", "capacity in bytes")
     use_map = Param.Bool(False, "enable sparse memory")
     map_levels = Param.Int(4, "sparse memory map levels")
+    numa_high_bit = Param.Int(0, "numa high bit")