mem-ruby: Cleanup filters
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Sun, 5 May 2019 15:22:56 +0000 (17:22 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Sat, 6 Jul 2019 22:55:32 +0000 (22:55 +0000)
Renamed member variables to comply with general naming
conventional outside of the ruby folder so that the
filters can be moved out.

Moved code to base to reduce code duplication.

Renamed the private get_index functions to hash, to make their
functionality explicit.

Change-Id: Ic6519cfc5e09ea95bc502a29b27f750f04eda754
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18734
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
15 files changed:
src/mem/ruby/filters/AbstractBloomFilter.hh
src/mem/ruby/filters/BlockBloomFilter.cc
src/mem/ruby/filters/BlockBloomFilter.hh
src/mem/ruby/filters/BulkBloomFilter.cc
src/mem/ruby/filters/BulkBloomFilter.hh
src/mem/ruby/filters/H3BloomFilter.cc
src/mem/ruby/filters/H3BloomFilter.hh
src/mem/ruby/filters/LSB_CountingBloomFilter.cc
src/mem/ruby/filters/LSB_CountingBloomFilter.hh
src/mem/ruby/filters/MultiBitSelBloomFilter.cc
src/mem/ruby/filters/MultiBitSelBloomFilter.hh
src/mem/ruby/filters/MultiGrainBloomFilter.cc
src/mem/ruby/filters/MultiGrainBloomFilter.hh
src/mem/ruby/filters/NonCountingBloomFilter.cc
src/mem/ruby/filters/NonCountingBloomFilter.hh

index 3e90cadd9350358d9f186c82782e372e46d600ec..851e5d9bef428fd05f348e8d379627f6e85ecaf4 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2019 Inria
  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Daniel Carvalho
  */
 
 #ifndef __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__
 #define __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__
 
-#include "mem/ruby/common/Address.hh"
+#include <vector>
+
+#include "base/intmath.hh"
+#include "base/types.hh"
 
 class AbstractBloomFilter
 {
+  protected:
+    /** The filter itself. */
+    std::vector<int> filter;
+
+    /** Number of bits needed to represent the size of the filter. */
+    const int sizeBits;
+
   public:
+    /**
+     * Create and clear the filter.
+     */
+    AbstractBloomFilter(std::size_t size)
+        : filter(size), sizeBits(floorLog2(size))
+    {
+        clear();
+    }
     virtual ~AbstractBloomFilter() {};
-    virtual void clear() = 0;
-    virtual void merge(AbstractBloomFilter * other_filter) = 0;
+
+    /**
+     * Clear the filter by resetting all values.
+     */
+    virtual void clear()
+    {
+        for (auto& entry : filter) {
+            entry = 0;
+        }
+    }
+
+    /** Merges the contents of both filters into this'. */
+    virtual void merge(const AbstractBloomFilter* other) {}
+
+    /**
+     * Perform the filter specific function to set the corresponding
+     * entries (can be multiple) of an address.
+     *
+     * @param addr The address being parsed.
+     */
     virtual void set(Addr addr) = 0;
 
     /**
@@ -48,9 +87,36 @@ class AbstractBloomFilter
      */
     virtual void unset(Addr addr) {};
 
+    /**
+     * Check if the corresponding filter entries of an address should be
+     * considered as set.
+     *
+     * @param addr The address being parsed.
+     * @return Whether the respective filter entry is set.
+     */
     virtual bool isSet(Addr addr) = 0;
-    virtual int getCount(Addr addr) = 0;
-    virtual int getTotalCount() = 0;
+
+    /**
+     * Get the value stored in the corresponding filter entry of an address.
+     *
+     * @param addr The address being parsed.
+     * @param Get the value stored in the respective filter entry.
+     */
+    virtual int getCount(Addr addr) { return 0; }
+
+    /**
+     * Get the total value stored in the filter entries.
+     *
+     * @return The sum of all filter entries.
+     */
+    virtual int getTotalCount() const
+    {
+        int count = 0;
+        for (const auto& entry : filter) {
+            count += entry;
+        }
+        return count;
+    }
 };
 
 #endif // __MEM_RUBY_FILTERS_ABSTRACTBLOOMFILTER_HH__
index 3516928859b16b0dbc339143fd45b3ddc4f74752..f9942fe719f5140b65e8a01306cc878032e1cab5 100644 (file)
 
 #include "mem/ruby/filters/BlockBloomFilter.hh"
 
-#include "base/intmath.hh"
+#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
 
 BlockBloomFilter::BlockBloomFilter(int size)
+    : AbstractBloomFilter(size)
 {
-    m_filter_size = size;
-    m_filter_size_bits = floorLog2(m_filter_size);
-
-    m_filter.resize(m_filter_size);
-
-    clear();
 }
 
 BlockBloomFilter::~BlockBloomFilter()
 {
 }
 
-void
-BlockBloomFilter::clear()
-{
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-}
-
-void
-BlockBloomFilter::merge(AbstractBloomFilter * other_filter)
-{
-    // TODO
-}
-
 void
 BlockBloomFilter::set(Addr addr)
 {
-    int i = get_index(addr);
-    m_filter[i] = 1;
+    filter[hash(addr)] = 1;
 }
 
 void
 BlockBloomFilter::unset(Addr addr)
 {
-    int i = get_index(addr);
-    m_filter[i] = 0;
+    filter[hash(addr)] = 0;
 }
 
 bool
 BlockBloomFilter::isSet(Addr addr)
 {
-    int i = get_index(addr);
-    return (m_filter[i]);
+    return filter[hash(addr)];
 }
 
 int
 BlockBloomFilter::getCount(Addr addr)
 {
-    return m_filter[get_index(addr)];
-}
-
-int
-BlockBloomFilter::getTotalCount()
-{
-    int count = 0;
-
-    for (int i = 0; i < m_filter_size; i++) {
-        if (m_filter[i]) {
-            count++;
-        }
-    }
-    return count;
+    return filter[hash(addr)];
 }
 
 int
-BlockBloomFilter::get_index(Addr addr)
+BlockBloomFilter::hash(Addr addr) const
 {
     // Pull out some bit field ==> B1
     // Pull out additional bits, not the same as B1 ==> B2
@@ -111,9 +76,9 @@ BlockBloomFilter::get_index(Addr addr)
     Addr other_bits = bitSelect(addr,
                        2 * RubySystem::getBlockSizeBits() + offset,
                        2 * RubySystem::getBlockSizeBits() + offset +
-                       m_filter_size_bits - 1);
+                       sizeBits - 1);
     int index = block_bits ^ other_bits;
-    assert(index < m_filter_size);
+    assert(index < filter.size());
     return index;
 }
 
index 5eaf6ead321e5cbc93f7ee83ddce16d8aabe0375..7c8ffc19cffff3c67f6dd3dbb7b51f07bdaa1850 100644 (file)
@@ -29,9 +29,6 @@
 #ifndef __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__
 #define __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__
 
-#include <vector>
-
-#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
 class BlockBloomFilter : public AbstractBloomFilter
@@ -40,21 +37,14 @@ class BlockBloomFilter : public AbstractBloomFilter
     BlockBloomFilter(int size);
     ~BlockBloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
+    void set(Addr addr) override;
     void unset(Addr addr) override;
 
     bool isSet(Addr addr);
     int getCount(Addr addr);
-    int getTotalCount();
 
   private:
-    int get_index(Addr addr);
-
-    std::vector<int> m_filter;
-    int m_filter_size;
-    int m_filter_size_bits;
+    int hash(Addr addr) const;
 };
 
 #endif // __MEM_RUBY_FILTERS_BLOCKBLOOMFILTER_HH__
index da873f9422db243a5938c0ed9e2cb40bf22cf778..a917a14918ba542f2ec9a382ad65eae1670f804d 100644 (file)
 
 #include "mem/ruby/filters/BulkBloomFilter.hh"
 
-#include <cassert>
-
-#include "base/intmath.hh"
+#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
 
 BulkBloomFilter::BulkBloomFilter(int size)
+    : AbstractBloomFilter(size), sectorBits(sizeBits - 1)
 {
-    m_filter_size = size;
-    m_filter_size_bits = floorLog2(m_filter_size);
-    // split the filter bits in half, c0 and c1
-    m_sector_bits = m_filter_size_bits - 1;
-
-    m_temp_filter.resize(m_filter_size);
-    m_filter.resize(m_filter_size);
-    clear();
-
-    // clear temp filter
-    for (int i = 0; i < m_filter_size; ++i) {
-        m_temp_filter[i] = 0;
-    }
 }
 
 BulkBloomFilter::~BulkBloomFilter()
 {
 }
 
-void
-BulkBloomFilter::clear()
-{
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-}
-
-void
-BulkBloomFilter::merge(AbstractBloomFilter * other_filter)
-{
-    // TODO
-}
-
 void
 BulkBloomFilter::set(Addr addr)
 {
     // c0 contains the cache index bits
-    int set_bits = m_sector_bits;
+    int set_bits = sectorBits;
     int block_bits = RubySystem::getBlockSizeBits();
     int c0 = bitSelect(addr, block_bits, block_bits + set_bits - 1);
-    // c1 contains the lower m_sector_bits permuted bits
+    // c1 contains the lower sectorBits permuted bits
     //Address permuted_bits = permute(addr);
     //int c1 = permuted_bits.bitSelect(0, set_bits-1);
     int c1 = bitSelect(addr, block_bits+set_bits, (block_bits+2*set_bits) - 1);
-    //assert(c0 < (m_filter_size/2));
-    //assert(c0 + (m_filter_size/2) < m_filter_size);
-    //assert(c1 < (m_filter_size/2));
+    //assert(c0 < (filter_size/2));
+    //assert(c0 + (filter_size/2) < filter_size);
+    //assert(c1 < (filter_size/2));
     // set v0 bit
-    m_filter[c0 + (m_filter_size/2)] = 1;
+    filter[c0 + (filter.size()/2)] = 1;
     // set v1 bit
-    m_filter[c1] = 1;
+    filter[c1] = 1;
 }
 
 bool
 BulkBloomFilter::isSet(Addr addr)
 {
     // c0 contains the cache index bits
-    int set_bits = m_sector_bits;
+    const int filter_size = filter.size();
+    int set_bits = sectorBits;
     int block_bits = RubySystem::getBlockSizeBits();
     int c0 = bitSelect(addr, block_bits, block_bits + set_bits - 1);
     // c1 contains the lower 10 permuted bits
     //Address permuted_bits = permute(addr);
     //int c1 = permuted_bits.bitSelect(0, set_bits-1);
     int c1 = bitSelect(addr, block_bits+set_bits, (block_bits+2*set_bits) - 1);
-    //assert(c0 < (m_filter_size/2));
-    //assert(c0 + (m_filter_size/2) < m_filter_size);
-    //assert(c1 < (m_filter_size/2));
+    //assert(c0 < (filter_size/2));
+    //assert(c0 + (filter_size/2) < filter_size);
+    //assert(c1 < (filter_size/2));
     // set v0 bit
-    m_temp_filter[c0 + (m_filter_size/2)] = 1;
+    std::vector<int> temp_filter(filter.size(), 0);
+    temp_filter[c0 + (filter_size/2)] = 1;
     // set v1 bit
-    m_temp_filter[c1] = 1;
+    temp_filter[c1] = 1;
 
     // perform filter intersection. If any c part is 0, no possibility
     // of address being in signature.  get first c intersection part
     bool zero = false;
-    for (int i = 0; i < m_filter_size/2; ++i){
+    for (int i = 0; i < filter_size/2; ++i){
         // get intersection of signatures
-        m_temp_filter[i] = m_temp_filter[i] && m_filter[i];
-        zero = zero || m_temp_filter[i];
+        temp_filter[i] = temp_filter[i] && filter[i];
+        zero = zero || temp_filter[i];
     }
     zero = !zero;
     if (zero) {
         // one section is zero, no possiblility of address in signature
         // reset bits we just set
-        m_temp_filter[c0 + (m_filter_size / 2)] = 0;
-        m_temp_filter[c1] = 0;
+        temp_filter[c0 + (filter_size / 2)] = 0;
+        temp_filter[c1] = 0;
         return false;
     }
 
     // check second section
     zero = false;
-    for (int i = m_filter_size / 2; i < m_filter_size; ++i) {
+    for (int i = filter_size / 2; i < filter_size; ++i) {
         // get intersection of signatures
-        m_temp_filter[i] =  m_temp_filter[i] && m_filter[i];
-        zero = zero || m_temp_filter[i];
+        temp_filter[i] =  temp_filter[i] && filter[i];
+        zero = zero || temp_filter[i];
     }
     zero = !zero;
     if (zero) {
         // one section is zero, no possiblility of address in signature
-        m_temp_filter[c0 + (m_filter_size / 2)] = 0;
-        m_temp_filter[c1] = 0;
+        temp_filter[c0 + (filter_size / 2)] = 0;
+        temp_filter[c1] = 0;
         return false;
     }
     // one section has at least one bit set
-    m_temp_filter[c0 + (m_filter_size / 2)] = 0;
-    m_temp_filter[c1] = 0;
+    temp_filter[c0 + (filter_size / 2)] = 0;
+    temp_filter[c1] = 0;
     return true;
 }
 
@@ -151,28 +125,8 @@ BulkBloomFilter::getCount(Addr addr)
     return 0;
 }
 
-int
-BulkBloomFilter::getTotalCount()
-{
-    int count = 0;
-    for (int i = 0; i < m_filter_size; i++) {
-        if (m_filter[i]) {
-            count++;
-        }
-    }
-    return count;
-}
-
-int
-BulkBloomFilter::get_index(Addr addr)
-{
-    return bitSelect(addr, RubySystem::getBlockSizeBits(),
-                     RubySystem::getBlockSizeBits() +
-                     m_filter_size_bits - 1);
-}
-
 Addr
-BulkBloomFilter::permute(Addr addr)
+BulkBloomFilter::hash(Addr addr) const
 {
     // permutes the original address bits according to Table 5
     int block_offset = RubySystem::getBlockSizeBits();
index 39cd8094409ca487a621dcfe46c691a5d1cdf411..b6f52b960f51977c5f75c939d085dee6b4bf7f70 100644 (file)
 
 #include <vector>
 
-#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+/**
+ * Implementation of the bloom filter, as described in "Bulk Disambiguation of
+ * Speculative Threads in Multiprocessors", by Ceze, Luis, et al.
+ */
 class BulkBloomFilter : public AbstractBloomFilter
 {
   public:
     BulkBloomFilter(int size);
     ~BulkBloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
+    void set(Addr addr) override;
 
     bool isSet(Addr addr);
     int getCount(Addr addr);
-    int getTotalCount();
 
   private:
-    int get_index(Addr addr);
-    Addr permute(Addr addr);
-
-    std::vector<int> m_filter;
-    std::vector<int> m_temp_filter;
-
-    int m_filter_size;
-    int m_filter_size_bits;
-
-    int m_sector_bits;
+    /** Permutes the address to generate its signature. */
+    Addr hash(Addr addr) const;
 
+    // split the filter bits in half, c0 and c1
+    const int sectorBits;
 };
 
 #endif // __MEM_RUBY_FILTERS_BULKBLOOMFILTER_HH__
index 7f44a2bd35f12a551f4676385ee814c7a3bb768d..f6ee8a1688d5f39d9bf2b8b27f9b75b105120636 100644 (file)
@@ -28,7 +28,8 @@
 
 #include "mem/ruby/filters/H3BloomFilter.hh"
 
-#include "base/intmath.hh"
+#include "base/logging.hh"
+#include "mem/ruby/common/Address.hh"
 
 static int H3[64][16] = {
     { 33268410,   395488709,  311024285,  456111753,
@@ -352,41 +353,11 @@ static int H3[64][16] = {
       394261773,  848616745,  15446017,   517723271,  },
 };
 
-H3BloomFilter::H3BloomFilter(int size, int hashes, bool parallel)
+H3BloomFilter::H3BloomFilter(int size, int num_hashes, bool parallel)
+    : AbstractBloomFilter(size), numHashes(num_hashes), isParallel(parallel),
+      parFilterSize(filter.size() / numHashes)
 {
-    //TODO: change this ugly init code...
-    primes_list[0] = 9323;
-    primes_list[1] = 11279;
-    primes_list[2] = 10247;
-    primes_list[3] = 30637;
-    primes_list[4] = 25717;
-    primes_list[5] = 43711;
-
-    mults_list[0] = 255;
-    mults_list[1] = 29;
-    mults_list[2] = 51;
-    mults_list[3] = 3;
-    mults_list[4] = 77;
-    mults_list[5] = 43;
-
-    adds_list[0] = 841;
-    adds_list[1] = 627;
-    adds_list[2] = 1555;
-    adds_list[3] = 241;
-    adds_list[4] = 7777;
-    adds_list[5] = 65931;
-
-    m_filter_size = size;
-    m_num_hashes = hashes;
-    isParallel = parallel;
-
-    m_filter_size_bits = floorLog2(m_filter_size);
-
-    m_par_filter_size = m_filter_size / m_num_hashes;
-    m_par_filter_size_bits = floorLog2(m_par_filter_size);
-
-    m_filter.resize(m_filter_size);
-    clear();
+    fatal_if(numHashes > 16, "There are only 16 hash functions implemented.");
 }
 
 H3BloomFilter::~H3BloomFilter()
@@ -394,29 +365,20 @@ H3BloomFilter::~H3BloomFilter()
 }
 
 void
-H3BloomFilter::clear()
+H3BloomFilter::merge(const AbstractBloomFilter *other)
 {
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-}
-
-void
-H3BloomFilter::merge(AbstractBloomFilter *other_filter)
-{
-    // assumes both filters are the same size!
-    H3BloomFilter * temp = (H3BloomFilter*) other_filter;
-    for (int i = 0; i < m_filter_size; ++i){
-        m_filter[i] |= (*temp)[i];
+    auto* cast_other = static_cast<const H3BloomFilter*>(other);
+    assert(filter.size() == cast_other->filter.size());
+    for (int i = 0; i < filter.size(); ++i){
+        filter[i] |= cast_other->filter[i];
     }
 }
 
 void
 H3BloomFilter::set(Addr addr)
 {
-    for (int i = 0; i < m_num_hashes; i++) {
-        int idx = get_index(addr, i);
-        m_filter[idx] = 1;
+    for (int i = 0; i < numHashes; i++) {
+        filter[hash(addr, i)] = 1;
     }
 }
 
@@ -425,9 +387,9 @@ H3BloomFilter::isSet(Addr addr)
 {
     bool res = true;
 
-    for (int i = 0; i < m_num_hashes; i++) {
-        int idx = get_index(addr, i);
-        res = res && m_filter[idx];
+    for (int i = 0; i < numHashes; i++) {
+        int idx = hash(addr, i);
+        res = res && filter[idx];
     }
     return res;
 }
@@ -439,32 +401,20 @@ H3BloomFilter::getCount(Addr addr)
 }
 
 int
-H3BloomFilter::getTotalCount()
-{
-    int count = 0;
-
-    for (int i = 0; i < m_filter_size; i++) {
-        count += m_filter[i];
-    }
-    return count;
-}
-
-int
-H3BloomFilter::get_index(Addr addr, int i)
+H3BloomFilter::hash(Addr addr, int hash_number) const
 {
     uint64_t x = makeLineAddress(addr);
-    // uint64_t y = (x*mults_list[i] + adds_list[i]) % primes_list[i];
-    int y = hash_H3(x,i);
+    int y = hashH3(x, hash_number);
 
     if (isParallel) {
-        return (y % m_par_filter_size) + i*m_par_filter_size;
+        return (y % parFilterSize) + hash_number * parFilterSize;
     } else {
-        return y % m_filter_size;
+        return y % filter.size();
     }
 }
 
 int
-H3BloomFilter::hash_H3(uint64_t value, int index)
+H3BloomFilter::hashH3(uint64_t value, int index) const
 {
     uint64_t mask = 1;
     uint64_t val = value;
index 1df0d2a16f1d4e34037a9fe5c777e86eb6813ee7..6cfa29337b23b5bf56b353e349f8aa8ed3e96374 100644 (file)
 #ifndef __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__
 #define __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__
 
-#include <vector>
-
-#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
+/**
+ * Implementation of the bloom filter as described in "Implementing Signatures
+ * for Transactional Memory", by Sanchez, Daniel, et al.
+ */
 class H3BloomFilter : public AbstractBloomFilter
 {
   public:
-    H3BloomFilter(int size, int hashes, bool parallel);
+    H3BloomFilter(int size, int num_hashes, bool parallel);
     ~H3BloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
-
+    void merge(const AbstractBloomFilter* other) override;
+    void set(Addr addr) override;
     bool isSet(Addr addr);
-    int getCount(Addr addr);
-    int getTotalCount();
-
-    int
-    operator[](const int index) const
-    {
-        return this->m_filter[index];
-    }
+    int getCount(Addr addr) override;
 
   private:
-    int get_index(Addr addr, int hashNumber);
+    /**
+     * Apply a hash functions to an address.
+     *
+     * @param addr The address to hash.
+     * @param hash_number Index of the H3 hash function to be used.
+     */
+    int hash(Addr addr, int hash_number) const;
 
-    int hash_H3(uint64_t value, int index);
+    /**
+     * Apply one of the H3 hash functions to a value.
+     *
+     * @param value The value to hash.
+     * @param hash_number Index of the hash function to be used.
+     */
+    int hashH3(uint64_t value, int hash_number) const;
 
-    std::vector<int> m_filter;
-    int m_filter_size;
-    int m_num_hashes;
-    int m_filter_size_bits;
-
-    int m_par_filter_size;
-    int m_par_filter_size_bits;
-
-    int primes_list[6];// = {9323,11279,10247,30637,25717,43711};
-    int mults_list[6]; //= {255,29,51,3,77,43};
-    int adds_list[6]; //= {841,627,1555,241,7777,65391};
+    /** The number of hashes used in this filter. Can be at most 16. */
+    const int numHashes;
 
+    /** Whether hashing should be performed in parallel. */
     bool isParallel;
+
+    /** Size of the filter when doing parallel hashing. */
+    int parFilterSize;
 };
 
 #endif // __MEM_RUBY_FILTERS_H3BLOOMFILTER_HH__
index 5d9475beda95651e60f58c27888dc0a9735e32d8..06e2d4f678f1dfc915cfbcf092b624d81bd43946 100644 (file)
 
 #include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
 
-#include "base/intmath.hh"
+#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
 
-LSB_CountingBloomFilter::LSB_CountingBloomFilter(int head, int tail)
+LSB_CountingBloomFilter::LSB_CountingBloomFilter(std::size_t filter_size,
+                                                 int max_value)
+    : AbstractBloomFilter(filter_size), maxValue(max_value)
 {
-    m_filter_size = head;
-    m_filter_size_bits = floorLog2(m_filter_size);
-
-    m_count = tail;
-    m_count_bits = floorLog2(m_count);
-
-    m_filter.resize(m_filter_size);
-    clear();
 }
 
 LSB_CountingBloomFilter::~LSB_CountingBloomFilter()
 {
 }
 
-void
-LSB_CountingBloomFilter::clear()
-{
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-}
-
-void
-LSB_CountingBloomFilter::merge(AbstractBloomFilter * other_filter)
-{
-    // TODO
-}
-
 void
 LSB_CountingBloomFilter::set(Addr addr)
 {
-    int i = get_index(addr);
-    if (m_filter[i] < m_count)
-        m_filter[i] += 1;
+    const int i = hash(addr);
+    if (filter[i] < maxValue)
+        filter[i] += 1;
 }
 
 void
 LSB_CountingBloomFilter::unset(Addr addr)
 {
-    int i = get_index(addr);
-    if (m_filter[i] > 0)
-        m_filter[i] -= 1;
+    const int i = hash(addr);
+    if (filter[i] > 0)
+        filter[i] -= 1;
 }
 
 bool
@@ -87,26 +67,15 @@ LSB_CountingBloomFilter::isSet(Addr addr)
 int
 LSB_CountingBloomFilter::getCount(Addr addr)
 {
-    return m_filter[get_index(addr)];
-}
-
-int
-LSB_CountingBloomFilter::getTotalCount()
-{
-    int count = 0;
-
-    for (int i = 0; i < m_filter_size; i++) {
-        count += m_filter[i];
-    }
-    return count;
+    return filter[hash(addr)];
 }
 
 int
-LSB_CountingBloomFilter::get_index(Addr addr)
+LSB_CountingBloomFilter::hash(Addr addr) const
 {
     return bitSelect(addr, RubySystem::getBlockSizeBits(),
                      RubySystem::getBlockSizeBits() +
-                     m_filter_size_bits - 1);
+                     sizeBits - 1);
 }
 
 
index 7c02f77269597db08d7d61bc208954b671f358f0..4fc635581b9089b91584648014a030539dccb9a7 100644 (file)
 #ifndef __MEM_RUBY_FILTERS_LSB_COUNTINGBLOOMFILTER_HH__
 #define __MEM_RUBY_FILTERS_LSB_COUNTINGBLOOMFILTER_HH__
 
-#include <vector>
-
-#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
 class LSB_CountingBloomFilter : public AbstractBloomFilter
 {
   public:
-    LSB_CountingBloomFilter(int head, int tail);
+    LSB_CountingBloomFilter(std::size_t filter_size, int max_value);
     ~LSB_CountingBloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
+    void set(Addr addr) override;
     void unset(Addr addr) override;
 
     bool isSet(Addr addr);
     int getCount(Addr addr);
-    int getTotalCount();
 
   private:
-    int get_index(Addr addr);
-
-    std::vector<int> m_filter;
-    int m_filter_size;
-    int m_filter_size_bits;
+    int hash(Addr addr) const;
 
-    int m_count_bits;
-    int m_count;
+    /** Maximum value of the filter entries. */
+    const int maxValue;
 };
 
 #endif //__MEM_RUBY_FILTERS_LSB_COUNTINGBLOOMFILTER_HH__
index f64e14eaba646633cd0e32d7e8c2d48db734b58b..aa1438fd3f1e921742c265aac132ea1ed1f908c6 100644 (file)
 
 #include "mem/ruby/filters/MultiBitSelBloomFilter.hh"
 
-#include <vector>
-
-#include "base/intmath.hh"
+#include "mem/ruby/common/Address.hh"
 
 MultiBitSelBloomFilter::MultiBitSelBloomFilter(std::size_t filter_size,
     int num_hashes, int skip_bits, bool is_parallel)
-    : m_filter_size(filter_size), m_num_hashes(num_hashes),
-      m_filter_size_bits(floorLog2(m_filter_size)), m_skip_bits(skip_bits),
-      m_par_filter_size(m_filter_size / m_num_hashes),
-      m_par_filter_size_bits(floorLog2(m_par_filter_size)),
+    : AbstractBloomFilter(filter_size), numHashes(num_hashes),
+      skipBits(skip_bits),
+      parFilterSize(filter_size / numHashes),
       isParallel(is_parallel)
 {
-    m_filter.resize(m_filter_size);
-    clear();
 }
 
 MultiBitSelBloomFilter::~MultiBitSelBloomFilter()
@@ -49,29 +44,21 @@ MultiBitSelBloomFilter::~MultiBitSelBloomFilter()
 }
 
 void
-MultiBitSelBloomFilter::clear()
-{
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-}
-
-void
-MultiBitSelBloomFilter::merge(AbstractBloomFilter *other_filter)
+MultiBitSelBloomFilter::merge(const AbstractBloomFilter *other)
 {
-    // assumes both filters are the same size!
-    MultiBitSelBloomFilter * temp = (MultiBitSelBloomFilter*) other_filter;
-    for (int i = 0; i < m_filter_size; ++i){
-        m_filter[i] |= (*temp)[i];
+    auto cast_other = static_cast<const MultiBitSelBloomFilter*>(other);
+    assert(filter.size() == cast_other->filter.size());
+    for (int i = 0; i < filter.size(); ++i){
+        filter[i] |= cast_other->filter[i];
     }
 }
 
 void
 MultiBitSelBloomFilter::set(Addr addr)
 {
-    for (int i = 0; i < m_num_hashes; i++) {
-        int idx = get_index(addr, i);
-        m_filter[idx] = 1;
+    for (int i = 0; i < numHashes; i++) {
+        int idx = hash(addr, i);
+        filter[idx] = 1;
     }
 }
 
@@ -80,9 +67,9 @@ MultiBitSelBloomFilter::isSet(Addr addr)
 {
     bool res = true;
 
-    for (int i=0; i < m_num_hashes; i++) {
-        int idx = get_index(addr, i);
-        res = res && m_filter[idx];
+    for (int i=0; i < numHashes; i++) {
+        int idx = hash(addr, i);
+        res = res && filter[idx];
     }
     return res;
 }
@@ -94,36 +81,22 @@ MultiBitSelBloomFilter::getCount(Addr addr)
 }
 
 int
-MultiBitSelBloomFilter::getTotalCount()
-{
-    int count = 0;
-
-    for (int i = 0; i < m_filter_size; i++) {
-        count += m_filter[i];
-    }
-    return count;
-}
-
-int
-MultiBitSelBloomFilter::get_index(Addr addr, int i)
+MultiBitSelBloomFilter::hash(Addr addr, int hash_number) const
 {
-    // m_skip_bits is used to perform BitSelect after skipping some
-    // bits. Used to simulate BitSel hashing on larger than cache-line
-    // granularities
-    uint64_t x = (makeLineAddress(addr) >> m_skip_bits);
-    int y = hash_bitsel(x, i, m_num_hashes, 30, m_filter_size_bits);
+    uint64_t x = (makeLineAddress(addr) >> skipBits);
+    int y = hashBitsel(x, hash_number, numHashes, 30, sizeBits);
     //36-bit addresses, 6-bit cache lines
 
     if (isParallel) {
-        return (y % m_par_filter_size) + i*m_par_filter_size;
+        return (y % parFilterSize) + hash_number * parFilterSize;
     } else {
-        return y % m_filter_size;
+        return y % filter.size();
     }
 }
 
 int
-MultiBitSelBloomFilter::hash_bitsel(uint64_t value, int index, int jump,
-                                    int maxBits, int numBits)
+MultiBitSelBloomFilter::hashBitsel(uint64_t value, int index, int jump,
+                                    int maxBits, int numBits) const
 {
     uint64_t mask = 1;
     int result = 0;
index 45952de9324362ca3df65ffef8081681e7c88277..2d69540040987656d5b9e238af102b4138828826 100644 (file)
 #ifndef __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__
 #define __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__
 
-#include <vector>
-
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/TypeDefines.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
 class MultiBitSelBloomFilter : public AbstractBloomFilter
@@ -42,37 +38,31 @@ class MultiBitSelBloomFilter : public AbstractBloomFilter
                            int skip_bits, bool is_parallel);
     ~MultiBitSelBloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
-
+    void merge(const AbstractBloomFilter* other) override;
+    void set(Addr addr) override;
     bool isSet(Addr addr);
     int getCount(Addr addr);
-    int getTotalCount();
-
-    int
-    operator[](const int index) const
-    {
-        return this->m_filter[index];
-    }
 
   private:
-    int get_index(Addr addr, int hashNumber);
+    int hash(Addr addr, int hash_number) const;
+
+    int hashBitsel(uint64_t value, int index, int jump, int maxBits,
+                    int numBits) const;
 
-    int hash_bitsel(uint64_t value, int index, int jump, int maxBits,
-                    int numBits);
+    /** Number of hashes. */
+    const int numHashes;
 
-    std::vector<int> m_filter;
-    int m_filter_size;
-    int m_num_hashes;
-    int m_filter_size_bits;
-    // Bit offset from block number
-    int m_skip_bits;
+    /**
+     * Bit offset from block number. Used to simulate bit selection hashing
+     * on larger than cache-line granularities, by skipping some bits.
+     */
+    const int skipBits;
 
-    int m_par_filter_size;
-    int m_par_filter_size_bits;
+    /** Size of the filter when doing parallel hashing. */
+    const int parFilterSize;
 
-    bool isParallel;
+    /** Whether hashing should be performed in parallel. */
+    const bool isParallel;
 };
 
 #endif // __MEM_RUBY_FILTERS_MULTIBITSELBLOOMFILTER_HH__
index a1f8993c901eb810cbdb8c60b56b16cfb8d7c81b..76016b2ff8abd883e0e35556b1eba8bf82b4bb0e 100644 (file)
 
 #include "mem/ruby/filters/MultiGrainBloomFilter.hh"
 
-#include "base/intmath.hh"
+#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
 
 MultiGrainBloomFilter::MultiGrainBloomFilter(int head, int tail)
+    : AbstractBloomFilter(head),
+      pageFilter(tail), pageFilterSizeBits(floorLog2(tail))
 {
-    // head contains size of 1st bloom filter, tail contains size of
-    // 2nd bloom filter
-    m_filter_size = head;
-    m_filter_size_bits = floorLog2(m_filter_size);
-
-    m_page_filter_size = tail;
-    m_page_filter_size_bits = floorLog2(m_page_filter_size);
-
-    m_filter.resize(m_filter_size);
-    m_page_filter.resize(m_page_filter_size);
-    clear();
 }
 
 MultiGrainBloomFilter::~MultiGrainBloomFilter()
@@ -53,39 +44,31 @@ MultiGrainBloomFilter::~MultiGrainBloomFilter()
 void
 MultiGrainBloomFilter::clear()
 {
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-    for (int i=0; i < m_page_filter_size; ++i){
-        m_page_filter[i] = 0;
+    AbstractBloomFilter::clear();
+    for (auto& entry : pageFilter){
+        entry = 0;
     }
 }
 
-void
-MultiGrainBloomFilter::merge(AbstractBloomFilter *other_filter)
-{
-    // TODO
-}
-
 void
 MultiGrainBloomFilter::set(Addr addr)
 {
-    int i = get_block_index(addr);
-    assert(i < m_filter_size);
-    assert(get_page_index(addr) < m_page_filter_size);
-    m_filter[i] = 1;
-    m_page_filter[i] = 1;
+    int i = hash(addr);
+    assert(i < filter.size());
+    assert(pageHash(addr) < pageFilter.size());
+    filter[i] = 1;
+    pageFilter[i] = 1;
 
 }
 
 bool
 MultiGrainBloomFilter::isSet(Addr addr)
 {
-    int i = get_block_index(addr);
-    assert(i < m_filter_size);
-    assert(get_page_index(addr) < m_page_filter_size);
+    int i = hash(addr);
+    assert(i < filter.size());
+    assert(pageHash(addr) < pageFilter.size());
     // we have to have both indices set
-    return (m_filter[i] && m_page_filter[i]);
+    return (filter[i] && pageFilter[i]);
 }
 
 int
@@ -96,37 +79,33 @@ MultiGrainBloomFilter::getCount(Addr addr)
 }
 
 int
-MultiGrainBloomFilter::getTotalCount()
+MultiGrainBloomFilter::getTotalCount() const
 {
-    int count = 0;
-
-    for (int i = 0; i < m_filter_size; i++) {
-        count += m_filter[i];
-    }
+    int count = AbstractBloomFilter::getTotalCount();
 
-    for (int i=0; i < m_page_filter_size; ++i) {
-        count += m_page_filter[i];
+    for (const auto& entry : pageFilter) {
+        count += entry;
     }
 
     return count;
 }
 
 int
-MultiGrainBloomFilter::get_block_index(Addr addr)
+MultiGrainBloomFilter::hash(Addr addr) const
 {
     // grap a chunk of bits after byte offset
     return bitSelect(addr, RubySystem::getBlockSizeBits(),
                      RubySystem::getBlockSizeBits() +
-                     m_filter_size_bits - 1);
+                     sizeBits - 1);
 }
 
 int
-MultiGrainBloomFilter::get_page_index(Addr addr)
+MultiGrainBloomFilter::pageHash(Addr addr) const
 {
-    int bits = RubySystem::getBlockSizeBits() + m_filter_size_bits - 1;
+    int bits = RubySystem::getBlockSizeBits() + sizeBits - 1;
 
     // grap a chunk of bits after first chunk
-    return bitSelect(addr, bits, bits + m_page_filter_size_bits - 1);
+    return bitSelect(addr, bits, bits + pageFilterSizeBits - 1);
 }
 
 
index 6f9a584783b1feca1d1e103265c15c0bac2acd45..148f42df21a5b838b6e43efd107ffa08cbb52c66 100644 (file)
 
 #include <vector>
 
-#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
 class MultiGrainBloomFilter : public AbstractBloomFilter
 {
   public:
+    /**
+     * @param head Size of 1st bloom filter.
+     * @param tail size of 2nd bloom filter.
+     */
     MultiGrainBloomFilter(int head, int tail);
     ~MultiGrainBloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
+    void clear() override;
+    void set(Addr addr) override;
 
     bool isSet(Addr addr);
     int getCount(Addr addr);
-    int getTotalCount();
+    int getTotalCount() const override;
 
   private:
-    int get_block_index(Addr addr);
-    int get_page_index(Addr addr);
+    int hash(Addr addr) const;
+    int pageHash(Addr addr) const;
 
-    // The block filter
-    std::vector<int> m_filter;
-    int m_filter_size;
-    int m_filter_size_bits;
-    // The page number filter
-    std::vector<int> m_page_filter;
-    int m_page_filter_size;
-    int m_page_filter_size_bits;
+    // The block filter uses the filter vector declared in the base class
+    /** The page number filter. */
+    std::vector<int> pageFilter;
+    int pageFilterSizeBits;
 };
 
 #endif // __MEM_RUBY_FILTERS_MULTIGRAINBLOOMFILTER_HH__
index 50432d7a85cc00c8ac26c7ab8b7f137102acb2b1..46e74d244dcd38bb9aab0a67f893f76d2f48fc5f 100644 (file)
 
 #include "mem/ruby/filters/NonCountingBloomFilter.hh"
 
-#include "base/intmath.hh"
-#include "base/str.hh"
+#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/system/RubySystem.hh"
 
-NonCountingBloomFilter::NonCountingBloomFilter(int head, int tail)
+NonCountingBloomFilter::NonCountingBloomFilter(std::size_t size, int skip_bits)
+    : AbstractBloomFilter(size), skipBits(skip_bits)
 {
-    // head contains filter size, tail contains bit offset from block number
-    m_filter_size = head;
-    m_offset = tail;
-    m_filter_size_bits = floorLog2(m_filter_size);
-
-    m_filter.resize(m_filter_size);
-    clear();
 }
 
 NonCountingBloomFilter::~NonCountingBloomFilter()
@@ -48,68 +41,46 @@ NonCountingBloomFilter::~NonCountingBloomFilter()
 }
 
 void
-NonCountingBloomFilter::clear()
-{
-    for (int i = 0; i < m_filter_size; i++) {
-        m_filter[i] = 0;
-    }
-}
-
-void
-NonCountingBloomFilter::merge(AbstractBloomFilter *other_filter)
+NonCountingBloomFilter::merge(const AbstractBloomFilter *other)
 {
-    // assumes both filters are the same size!
-    NonCountingBloomFilter * temp = (NonCountingBloomFilter*) other_filter;
-    for (int i = 0; i < m_filter_size; ++i){
-        m_filter[i] |= (*temp)[i];
+    auto* cast_other = static_cast<const NonCountingBloomFilter*>(other);
+    assert(filter.size() == cast_other->filter.size());
+    for (int i = 0; i < filter.size(); ++i){
+        filter[i] |= cast_other->filter[i];
     }
 }
 
 void
 NonCountingBloomFilter::set(Addr addr)
 {
-    int i = get_index(addr);
-    m_filter[i] = 1;
+    filter[hash(addr)] = 1;
 }
 
 void
 NonCountingBloomFilter::unset(Addr addr)
 {
-    int i = get_index(addr);
-    m_filter[i] = 0;
+    filter[hash(addr)] = 0;
 }
 
 bool
 NonCountingBloomFilter::isSet(Addr addr)
 {
-    int i = get_index(addr);
-    return (m_filter[i]);
+    return filter[hash(addr)];
 }
 
 
 int
 NonCountingBloomFilter::getCount(Addr addr)
 {
-    return m_filter[get_index(addr)];
-}
-
-int
-NonCountingBloomFilter::getTotalCount()
-{
-    int count = 0;
-
-    for (int i = 0; i < m_filter_size; i++) {
-        count += m_filter[i];
-    }
-    return count;
+    return filter[hash(addr)];
 }
 
 int
-NonCountingBloomFilter::get_index(Addr addr)
+NonCountingBloomFilter::hash(Addr addr) const
 {
-    return bitSelect(addr, RubySystem::getBlockSizeBits() + m_offset,
-                     RubySystem::getBlockSizeBits() + m_offset +
-                     m_filter_size_bits - 1);
+    return bitSelect(addr, RubySystem::getBlockSizeBits() + skipBits,
+                     RubySystem::getBlockSizeBits() + skipBits +
+                     sizeBits - 1);
 }
 
 
index 08610606ee0d911d20fb447a72d860d89de2b155..08c84ee7c495668907d523383ad3fa28c7edf6ed 100644 (file)
 #ifndef __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__
 #define __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__
 
-#include <vector>
-
-#include "mem/ruby/common/Address.hh"
 #include "mem/ruby/filters/AbstractBloomFilter.hh"
 
 class NonCountingBloomFilter : public AbstractBloomFilter
 {
   public:
-    NonCountingBloomFilter(int head, int tail);
+    NonCountingBloomFilter(std::size_t filter_size, int skip_bits);
     ~NonCountingBloomFilter();
 
-    void clear();
-    void merge(AbstractBloomFilter * other_filter);
-    void set(Addr addr);
+    void merge(const AbstractBloomFilter* other) override;
+    void set(Addr addr) override;
     void unset(Addr addr) override;
 
     bool isSet(Addr addr);
     int getCount(Addr addr);
-    int getTotalCount();
-
-    int
-    operator[](const int index) const
-    {
-        return this->m_filter[index];
-    }
 
   private:
-    int get_index(Addr addr);
+    int hash(Addr addr) const;
 
-    std::vector<int> m_filter;
-    int m_filter_size;
-    int m_offset;
-    int m_filter_size_bits;
+    /**
+     * Bit offset from block number. Used to simulate bit selection hashing
+     * on larger than cache-line granularities, by skipping some bits.
+     */
+    int skipBits;
 };
 
 #endif // __MEM_RUBY_FILTERS_NONCOUNTINGBLOOMFILTER_HH__