2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "base/intmath.hh"
32 #include "base/str.hh"
33 #include "mem/ruby/filters/BulkBloomFilter.hh"
34 #include "mem/ruby/system/System.hh"
38 BulkBloomFilter::BulkBloomFilter(string str
)
45 split_first(str
, head
, tail
, '_');
48 m_filter_size
= atoi(head
.c_str());
49 m_filter_size_bits
= floorLog2(m_filter_size
);
50 // split the filter bits in half, c0 and c1
51 m_sector_bits
= m_filter_size_bits
- 1;
53 m_temp_filter
.resize(m_filter_size
);
54 m_filter
.resize(m_filter_size
);
58 for (int i
= 0; i
< m_filter_size
; ++i
) {
63 BulkBloomFilter::~BulkBloomFilter()
68 BulkBloomFilter::clear()
70 for (int i
= 0; i
< m_filter_size
; i
++) {
76 BulkBloomFilter::increment(const Address
& addr
)
82 BulkBloomFilter::decrement(const Address
& addr
)
88 BulkBloomFilter::merge(AbstractBloomFilter
* other_filter
)
94 BulkBloomFilter::set(const Address
& addr
)
96 // c0 contains the cache index bits
97 int set_bits
= m_sector_bits
;
98 int block_bits
= RubySystem::getBlockSizeBits();
99 int c0
= addr
.bitSelect( block_bits
, block_bits
+ set_bits
- 1);
100 // c1 contains the lower m_sector_bits permuted bits
101 //Address permuted_bits = permute(addr);
102 //int c1 = permuted_bits.bitSelect(0, set_bits-1);
103 int c1
= addr
.bitSelect( block_bits
+set_bits
, (block_bits
+2*set_bits
) - 1);
104 //assert(c0 < (m_filter_size/2));
105 //assert(c0 + (m_filter_size/2) < m_filter_size);
106 //assert(c1 < (m_filter_size/2));
108 m_filter
[c0
+ (m_filter_size
/2)] = 1;
114 BulkBloomFilter::unset(const Address
& addr
)
120 BulkBloomFilter::isSet(const Address
& addr
)
122 // c0 contains the cache index bits
123 int set_bits
= m_sector_bits
;
124 int block_bits
= RubySystem::getBlockSizeBits();
125 int c0
= addr
.bitSelect( block_bits
, block_bits
+ set_bits
- 1);
126 // c1 contains the lower 10 permuted bits
127 //Address permuted_bits = permute(addr);
128 //int c1 = permuted_bits.bitSelect(0, set_bits-1);
129 int c1
= addr
.bitSelect( block_bits
+set_bits
, (block_bits
+2*set_bits
) - 1);
130 //assert(c0 < (m_filter_size/2));
131 //assert(c0 + (m_filter_size/2) < m_filter_size);
132 //assert(c1 < (m_filter_size/2));
134 m_temp_filter
[c0
+ (m_filter_size
/2)] = 1;
136 m_temp_filter
[c1
] = 1;
138 // perform filter intersection. If any c part is 0, no possibility
139 // of address being in signature. get first c intersection part
141 for (int i
= 0; i
< m_filter_size
/2; ++i
){
142 // get intersection of signatures
143 m_temp_filter
[i
] = m_temp_filter
[i
] && m_filter
[i
];
144 zero
= zero
|| m_temp_filter
[i
];
148 // one section is zero, no possiblility of address in signature
149 // reset bits we just set
150 m_temp_filter
[c0
+ (m_filter_size
/ 2)] = 0;
151 m_temp_filter
[c1
] = 0;
155 // check second section
157 for(int i
= m_filter_size
/ 2; i
< m_filter_size
; ++i
) {
158 // get intersection of signatures
159 m_temp_filter
[i
] = m_temp_filter
[i
] && m_filter
[i
];
160 zero
= zero
|| m_temp_filter
[i
];
164 // one section is zero, no possiblility of address in signature
165 m_temp_filter
[c0
+ (m_filter_size
/ 2)] = 0;
166 m_temp_filter
[c1
] = 0;
169 // one section has at least one bit set
170 m_temp_filter
[c0
+ (m_filter_size
/ 2)] = 0;
171 m_temp_filter
[c1
] = 0;
176 BulkBloomFilter::getCount(const Address
& addr
)
183 BulkBloomFilter::getTotalCount()
186 for (int i
= 0; i
< m_filter_size
; i
++) {
195 BulkBloomFilter::getIndex(const Address
& addr
)
197 return get_index(addr
);
201 BulkBloomFilter::readBit(const int index
)
208 BulkBloomFilter::writeBit(const int index
, const int value
)
214 BulkBloomFilter::print(ostream
& out
) const
219 BulkBloomFilter::get_index(const Address
& addr
)
221 return addr
.bitSelect(RubySystem::getBlockSizeBits(),
222 RubySystem::getBlockSizeBits() +
223 m_filter_size_bits
- 1);
227 BulkBloomFilter::permute(const Address
& addr
)
229 // permutes the original address bits according to Table 5
230 int block_offset
= RubySystem::getBlockSizeBits();
231 physical_address_t part1
= addr
.bitSelect(block_offset
, block_offset
+ 6),
232 part2
= addr
.bitSelect(block_offset
+ 9, block_offset
+ 9),
233 part3
= addr
.bitSelect(block_offset
+ 11, block_offset
+ 11),
234 part4
= addr
.bitSelect(block_offset
+ 17, block_offset
+ 17),
235 part5
= addr
.bitSelect(block_offset
+ 7, block_offset
+ 8),
236 part6
= addr
.bitSelect(block_offset
+ 10, block_offset
+ 10),
237 part7
= addr
.bitSelect(block_offset
+ 12, block_offset
+ 12),
238 part8
= addr
.bitSelect(block_offset
+ 13, block_offset
+ 13),
239 part9
= addr
.bitSelect(block_offset
+ 15, block_offset
+ 16),
240 part10
= addr
.bitSelect(block_offset
+ 18, block_offset
+ 20),
241 part11
= addr
.bitSelect(block_offset
+ 14, block_offset
+ 14);
243 physical_address_t result
=
244 (part1
<< 14) | (part2
<< 13) | (part3
<< 12) | (part4
<< 11) |
245 (part5
<< 9) | (part6
<< 8) | (part7
<< 7) | (part8
<< 6) |
246 (part9
<< 4) | (part10
<< 1) | (part11
);
248 // assume 32 bit addresses (both virtual and physical)
249 // select the remaining high-order 11 bits
250 physical_address_t remaining_bits
=
251 addr
.bitSelect(block_offset
+ 21, 31) << 21;
252 result
= result
| remaining_bits
;
254 return Address(result
);