From 4f044605e8a87873228933b4700e3e0ac9af27e5 Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Sun, 21 Mar 2010 21:22:21 -0700 Subject: [PATCH] ruby: Adds configurable bit selection for numa mapping --- configs/common/Options.py | 2 ++ src/mem/ruby/common/Address.hh | 30 ++++++++++++++++++++++++++ src/mem/ruby/system/DirectoryMemory.cc | 23 ++++++++++++++------ src/mem/ruby/system/DirectoryMemory.hh | 1 + src/mem/ruby/system/DirectoryMemory.py | 1 + 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/configs/common/Options.py b/configs/common/Options.py index b0153f453..e7ab0d86b 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -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) diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index 44dff7d83..7da5ed0fe 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -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 { diff --git a/src/mem/ruby/system/DirectoryMemory.cc b/src/mem/ruby/system/DirectoryMemory.cc index 2c32eacdc..d8037aec1 100644 --- a/src/mem/ruby/system/DirectoryMemory.cc +++ b/src/mem/ruby/system/DirectoryMemory.cc @@ -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) diff --git a/src/mem/ruby/system/DirectoryMemory.hh b/src/mem/ruby/system/DirectoryMemory.hh index 455329cd0..8b23ced02 100644 --- a/src/mem/ruby/system/DirectoryMemory.hh +++ b/src/mem/ruby/system/DirectoryMemory.hh @@ -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; diff --git a/src/mem/ruby/system/DirectoryMemory.py b/src/mem/ruby/system/DirectoryMemory.py index 9892f3135..784ed628f 100644 --- a/src/mem/ruby/system/DirectoryMemory.py +++ b/src/mem/ruby/system/DirectoryMemory.py @@ -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") -- 2.30.2