gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
sat_counter.test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Inria
3  * All rights reserved
4  *
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.
15  *
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.
27  *
28  * Authors: Daniel Carvalho
29  */
30 
31 #include <gtest/gtest-spi.h>
32 #include <gtest/gtest.h>
33 
34 #include <utility>
35 
36 #include "base/sat_counter.hh"
37 
41 TEST(SatCounterTest, MaximumValue)
42 {
43  const unsigned bits = 3;
44  const unsigned max_value = (1 << bits) - 1;
45  SatCounter counter(bits);
46 
47  for (int i = 0; i < 2*max_value; i++) {
48  counter++;
49  }
50 
51  ASSERT_EQ(counter, max_value);
52 }
53 
57 TEST(SatCounterTest, MinimumValue)
58 {
59  const unsigned bits = 3;
60  SatCounter counter(bits);
61 
62  for (int i = 0; i < 2; i++) {
63  counter--;
64  }
65 
66  ASSERT_EQ(counter, 0);
67 }
68 
72 TEST(SatCounterTest, InitialValue)
73 {
74  const unsigned bits = 3;
75  const unsigned initial_value = 4;
76  SatCounter counter(bits, initial_value);
77  ASSERT_EQ(counter, initial_value);
78  counter++;
79  counter.reset();
80  ASSERT_EQ(counter, initial_value);
81 }
82 
86 TEST(SatCounterTest, SaturationPercentile)
87 {
88  const unsigned bits = 3;
89  const unsigned max_value = (1 << bits) - 1;
90  SatCounter counter(bits);
91 
92  ASSERT_FALSE(counter.isSaturated());
93  for (double value = 0.0; value <= max_value; value++, counter++) {
94  const double saturation = value / max_value;
95  ASSERT_DOUBLE_EQ(counter.calcSaturation(), saturation);
96  }
97  ASSERT_TRUE(counter.isSaturated());
98 }
99 
103 TEST(SatCounterTest, Saturate)
104 {
105  const unsigned bits = 3;
106  const unsigned max_value = (1 << bits) - 1;
107  SatCounter counter(bits);
108  counter++;
109  ASSERT_FALSE(counter.isSaturated());
110 
111  // Make sure the value added is what was missing to saturate
112  const unsigned diff = counter.saturate();
113  ASSERT_EQ(diff, max_value - 1);
114  ASSERT_TRUE(counter.isSaturated());
115 }
116 
120 TEST(SatCounterTest, IntComparison)
121 {
122  const unsigned bits = 3;
123  SatCounter counter(bits);
124  int value = 0;
125 
126  ASSERT_EQ(counter++, value++);
127  ASSERT_EQ(counter++, value++);
128  ASSERT_EQ(counter--, value--);
129  ASSERT_EQ(counter++, value++);
130  ASSERT_EQ(counter++, value++);
131  ASSERT_EQ(counter--, value--);
132  ASSERT_EQ(counter++, value++);
133  ASSERT_EQ(counter--, value--);
134  ASSERT_EQ(counter--, value--);
135  ASSERT_EQ(counter++, value++);
136  ASSERT_EQ(counter--, value--);
137  ASSERT_EQ(counter--, value--);
138  ASSERT_EQ(counter, 0);
139 }
140 
144 TEST(SatCounterTest, Shift)
145 {
146  const unsigned bits = 3;
147  const unsigned max_value = (1 << bits) - 1;
148  const unsigned initial_value = 1;
149  SatCounter counter(bits, initial_value);
150  SatCounter other(bits, initial_value);
151  // The saturated shift value is just enough to saturate, since greater
152  // values could generate undefined behavior
153  SatCounter saturated_counter(bits, bits);
154  int value = initial_value;
155 
156  // Test random shifts
157  counter <<= 2;
158  value <<= 2;
159  ASSERT_EQ(counter, value);
160  counter >>= 1;
161  value >>= 1;
162  ASSERT_EQ(counter, value);
163 
164  // Test saturation
165  counter <<= bits;
166  ASSERT_EQ(counter, max_value);
167 
168  // Test zeroing
169  counter >>= bits;
170  ASSERT_EQ(counter, 0);
171 
172  // Test saturation against other saturating counter
173  counter.reset();
174  value = initial_value;
175  counter <<= other;
176  value <<= other;
177  ASSERT_EQ(counter, value);
178  counter <<= saturated_counter;
179  value = max_value;
180  ASSERT_EQ(counter, max_value);
181 
182  // Test zeroing against other saturating counter
183  counter >>= other;
184  value >>= other;
185  ASSERT_EQ(counter, value);
186  counter >>= saturated_counter;
187  ASSERT_EQ(counter, 0);
188 
189  // Make sure the counters cannot be shifted by negative numbers, since
190  // that is undefined behaviour
191  ASSERT_DEATH(counter >>= -1, "");
192  ASSERT_DEATH(counter <<= -1, "");
193 }
194 
198 TEST(SatCounterTest, PrePostOperators)
199 {
200  const unsigned bits = 3;
201  const unsigned max_value = (1 << bits) - 1;
202  SatCounter counter_pre(bits);
203  SatCounter counter_post(bits);
204 
205  for (int i = 0; i < 2*max_value; i++) {
206  counter_post++;
207  SatCounter value_pre = ++counter_pre;
208  ASSERT_EQ(counter_post, value_pre);
209  }
210 
211  ASSERT_EQ(counter_pre, max_value);
212  ASSERT_EQ(counter_post, max_value);
213 
214  for (int i = 0; i < 2*max_value; i++) {
215  counter_post--;
216  SatCounter value_pre = --counter_pre;
217  ASSERT_EQ(counter_post, value_pre);
218  }
219 
220  ASSERT_EQ(counter_pre, 0);
221  ASSERT_EQ(counter_post, 0);
222 }
223 
227 TEST(SatCounterTest, CopyMove)
228 {
229  const unsigned bits = 3;
230  const unsigned max_value = (1 << bits) - 1;
231  const unsigned initial_value = 1;
232  SatCounter counter(bits, initial_value);
233  SatCounter deep_copy(1);
234  SatCounter counter_copy(2);
235 
236  // Increase counter value so that we can check if the inner counter is
237  // being copied
238  counter++;
239 
240  // Copy counter using both the copy constructor and the copy assignment
241  SatCounter counter_copy_constructor(counter);
242  deep_copy = counter_copy = counter;
243  ASSERT_EQ(counter_copy_constructor, initial_value + 1);
244  ASSERT_EQ(counter_copy, initial_value + 1);
245  ASSERT_EQ(deep_copy, initial_value + 1);
246 
247  // Make sure max value is the same for all of them, and that modifying
248  // the copies does not modify the original
249  for (int i = 0; i < 2*max_value; i++) {
250  counter_copy_constructor++;
251  counter_copy++;
252  deep_copy++;
253  }
254  ASSERT_EQ(counter, initial_value + 1);
255  ASSERT_EQ(counter_copy_constructor, max_value);
256  ASSERT_EQ(counter_copy, max_value);
257  ASSERT_EQ(deep_copy, max_value);
258 
259  // Make sure initial value is the same for all of them
260  counter_copy_constructor.reset();
261  counter_copy.reset();
262  deep_copy.reset();
263  ASSERT_EQ(counter_copy_constructor, initial_value);
264  ASSERT_EQ(counter_copy, initial_value);
265  ASSERT_EQ(deep_copy, initial_value);
266 
267  // Now check move
268  SatCounter counter_move_constructor(std::move(counter));
269  ASSERT_EQ(counter, 0);
270  ASSERT_EQ(counter_move_constructor, initial_value + 1);
271 
272  SatCounter counter_move(bits);
273  counter_move = std::move(counter_move_constructor);
274  ASSERT_EQ(counter_move_constructor, 0);
275  ASSERT_EQ(counter_move, initial_value + 1);
276 }
277 
281 TEST(SatCounterTest, AddSubAssignment)
282 {
283  const unsigned bits = 3;
284  const unsigned max_value = (1 << bits) - 1;
285  SatCounter counter(bits);
286  SatCounter other(bits, 2);
287  SatCounter saturated_counter(bits, max_value);
288  int value = 0;
289 
290  // Test add-assignment for a few random values and then saturate
291  counter += 2;
292  value += 2;
293  ASSERT_EQ(counter, value);
294  counter += 3;
295  value += 3;
296  ASSERT_EQ(counter, value);
297  counter += max_value;
298  value = max_value;
299  ASSERT_EQ(counter, value);
300 
301  // Test subtract-assignment for a few random values until back to zero
302  counter -= 2;
303  value -= 2;
304  ASSERT_EQ(counter, value);
305  counter -= 3;
306  value -= 3;
307  ASSERT_EQ(counter, value);
308  counter -= max_value;
309  value = 0;
310  ASSERT_EQ(counter, value);
311 
312  // Test add-assignment of other saturating counter
313  counter += other;
314  value += other;
315  ASSERT_EQ(counter, value);
316  counter += saturated_counter;
317  value = max_value;
318  ASSERT_EQ(counter, saturated_counter);
319 
320  // Test subtract-assignment of other saturating counter
321  counter -= other;
322  value -= other;
323  ASSERT_EQ(counter, value);
324  counter -= saturated_counter;
325  ASSERT_EQ(counter, 0);
326 }
327 
331 TEST(SatCounterTest, NegativeAddSubAssignment)
332 {
333  const unsigned bits = 3;
334  const unsigned max_value = (1 << bits) - 1;
335  SatCounter counter(bits, max_value);
336  int value = max_value;
337 
338  // Test add-assignment for a few negative values until zero is reached
339  counter += -2;
340  value += -2;
341  ASSERT_EQ(counter, value);
342  counter += -3;
343  value += -3;
344  ASSERT_EQ(counter, value);
345  counter += (int)-max_value;
346  value = 0;
347  ASSERT_EQ(counter, value);
348 
349  // Test subtract-assignment for a few negative values until saturation
350  counter -= -2;
351  value -= -2;
352  ASSERT_EQ(counter, value);
353  counter -= -3;
354  value -= -3;
355  ASSERT_EQ(counter, value);
356  counter -= (int)-max_value;
357  value = max_value;
358  ASSERT_EQ(counter, value);
359 }
360 
Bitfield< 7 > i
TEST(SatCounterTest, MaximumValue)
Test if the maximum value is indeed the maximum value reachable.
double calcSaturation() const
Calculate saturation percentile of the current counter&#39;s value with regard to its maximum possible va...
Definition: sat_counter.hh:240
Implements an n bit saturating counter and provides methods to increment, decrement, and read it.
Definition: sat_counter.hh:57
void reset()
Reset the counter to its initial value.
Definition: sat_counter.hh:231
uint8_t saturate()
Saturate the counter.
Definition: sat_counter.hh:254
bool isSaturated() const
Whether the counter has achieved its maximum value or not.
Definition: sat_counter.hh:247
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72

Generated on Fri Feb 28 2020 16:26:58 for gem5 by doxygen 1.8.13