From 8b3ad17cc3189ed7470c82e9108669fe48541f43 Mon Sep 17 00:00:00 2001 From: Nilay Vaish Date: Wed, 11 Jan 2012 13:29:54 -0600 Subject: [PATCH] Ruby Sparse Memory: Add function for collating blocks This patch adds function to the Sparse Memory so that the blocks can be recorded in a cache trace. The blocks are added to the cache recorder which can later write them into a file. --- src/mem/ruby/system/SparseMemory.cc | 67 +++++++++++++++++++++++++++++ src/mem/ruby/system/SparseMemory.hh | 13 +++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/mem/ruby/system/SparseMemory.cc b/src/mem/ruby/system/SparseMemory.cc index 0cfd0d90c..db8d494f8 100644 --- a/src/mem/ruby/system/SparseMemory.cc +++ b/src/mem/ruby/system/SparseMemory.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2012 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,6 +27,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "debug/RubyCache.hh" #include "mem/ruby/system/SparseMemory.hh" #include "mem/ruby/system/System.hh" @@ -341,6 +344,70 @@ SparseMemory::lookup(const Address& address) return entry; } +void +SparseMemory::recordBlocks(int cntrl_id, CacheRecorder* tr) const +{ + queue unexplored_nodes[2]; + queue address_of_nodes[2]; + + unexplored_nodes[0].push(m_map_head); + address_of_nodes[0].push(0); + + int parity_of_level = 0; + physical_address_t address, temp_address; + Address curAddress; + + // Initiallize the high bit to be the total number of bits plus + // the block offset. However the highest bit index is one less + // than this value. + int highBit = m_total_number_of_bits + RubySystem::getBlockSizeBits(); + int lowBit; + + for (int cur_level = 0; cur_level < m_number_of_levels; cur_level++) { + + // create the appropriate address for this level + // Note: that set Address is inclusive of the specified range, + // thus the high bit is one less than the total number of bits + // used to create the address. + lowBit = highBit - m_number_of_bits_per_level[cur_level]; + + while (!unexplored_nodes[parity_of_level].empty()) { + + SparseMapType* node = unexplored_nodes[parity_of_level].front(); + unexplored_nodes[parity_of_level].pop(); + + address = address_of_nodes[parity_of_level].front(); + address_of_nodes[parity_of_level].pop(); + + SparseMapType::iterator iter; + + for (iter = node->begin(); iter != node->end(); iter++) { + SparseMemEntry entry = (*iter).second; + curAddress = (*iter).first; + + if (cur_level != (m_number_of_levels - 1)) { + // If not at the last level, put this node in the queue + unexplored_nodes[1 - parity_of_level].push( + (SparseMapType*)(entry)); + address_of_nodes[1 - parity_of_level].push(address | + (curAddress.getAddress() << lowBit)); + } else { + // If at the last level, add a trace record + temp_address = address | (curAddress.getAddress() + << lowBit); + DataBlock block = ((AbstractEntry*)entry)->getDataBlk(); + tr->addRecord(cntrl_id, temp_address, 0, RubyRequestType_ST, 0, + block); + } + } + } + + // Adjust the highBit value for the next level + highBit -= m_number_of_bits_per_level[cur_level]; + parity_of_level = 1 - parity_of_level; + } +} + void SparseMemory::print(ostream& out) const { diff --git a/src/mem/ruby/system/SparseMemory.hh b/src/mem/ruby/system/SparseMemory.hh index f4cc12f97..e4237dbcd 100644 --- a/src/mem/ruby/system/SparseMemory.hh +++ b/src/mem/ruby/system/SparseMemory.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2012 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,9 +33,9 @@ #include #include "base/hashmap.hh" -#include "mem/ruby/slicc_interface/AbstractEntry.hh" #include "mem/ruby/common/Address.hh" -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/recorder/CacheRecorder.hh" +#include "mem/ruby/slicc_interface/AbstractEntry.hh" typedef void* SparseMemEntry; typedef m5::hash_map SparseMapType; @@ -59,6 +60,14 @@ class SparseMemory void add(const Address& address, AbstractEntry*); void remove(const Address& address); + /*! + * Function for recording the contents of memory. This function walks + * through all the levels of the sparse memory in a breadth first + * fashion. This might need more memory than a depth first approach. + * But breadth first seems easier to me than a depth first approach. + */ + void recordBlocks(int cntrl_id, CacheRecorder *) const; + AbstractEntry* lookup(const Address& address); // Print cache contents