gem5  v20.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 
29 #include <gtest/gtest-spi.h>
30 #include <gtest/gtest.h>
31 
32 #include <utility>
33 
34 #include "base/sat_counter.hh"
35 
39 TEST(SatCounterTest, MaximumValue)
40 {
41  const unsigned bits = 3;
42  const unsigned max_value = (1 << bits) - 1;
43  SatCounter counter(bits);
44 
45  for (int i = 0; i < 2*max_value; i++) {
46  counter++;
47  }
48 
49  ASSERT_EQ(counter, max_value);
50 }
51 
55 TEST(SatCounterTest, MinimumValue)
56 {
57  const unsigned bits = 3;
58  SatCounter counter(bits);
59 
60  for (int i = 0; i < 2; i++) {
61  counter--;
62  }
63 
64  ASSERT_EQ(counter, 0);
65 }
66 
70 TEST(SatCounterTest, InitialValue)
71 {
72  const unsigned bits = 3;
73  const unsigned initial_value = 4;
74  SatCounter counter(bits, initial_value);
75  ASSERT_EQ(counter, initial_value);
76  counter++;
77  counter.reset();
78  ASSERT_EQ(counter, initial_value);
79 }
80 
84 TEST(SatCounterTest, SaturationPercentile)
85 {
86  const unsigned bits = 3;
87  const unsigned max_value = (1 << bits) - 1;
88  SatCounter counter(bits);
89 
90  ASSERT_FALSE(counter.isSaturated());
91  for (double value = 0.0; value <= max_value; value++, counter++) {
92  const double saturation = value / max_value;
93  ASSERT_DOUBLE_EQ(counter.calcSaturation(), saturation);
94  }
95  ASSERT_TRUE(counter.isSaturated());
96 }
97 
101 TEST(SatCounterTest, Saturate)
102 {
103  const unsigned bits = 3;
104  const unsigned max_value = (1 << bits) - 1;
105  SatCounter counter(bits);
106  counter++;
107  ASSERT_FALSE(counter.isSaturated());
108 
109  // Make sure the value added is what was missing to saturate
110  const unsigned diff = counter.saturate();
111  ASSERT_EQ(diff, max_value - 1);
112  ASSERT_TRUE(counter.isSaturated());
113 }
114 
118 TEST(SatCounterTest, IntComparison)
119 {
120  const unsigned bits = 3;
121  SatCounter counter(bits);
122  int value = 0;
123 
124  ASSERT_EQ(counter++, value++);
125  ASSERT_EQ(counter++, value++);
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, 0);
137 }
138 
142 TEST(SatCounterTest, Shift)
143 {
144  const unsigned bits = 3;
145  const unsigned max_value = (1 << bits) - 1;
146  const unsigned initial_value = 1;
147  SatCounter counter(bits, initial_value);
148  SatCounter other(bits, initial_value);
149  // The saturated shift value is just enough to saturate, since greater
150  // values could generate undefined behavior
151  SatCounter saturated_counter(bits, bits);
152  int value = initial_value;
153 
154  // Test random shifts
155  counter <<= 2;
156  value <<= 2;
157  ASSERT_EQ(counter, value);
158  counter >>= 1;
159  value >>= 1;
160  ASSERT_EQ(counter, value);
161 
162  // Test saturation
163  counter <<= bits;
164  ASSERT_EQ(counter, max_value);
165 
166  // Test zeroing
167  counter >>= bits;
168  ASSERT_EQ(counter, 0);
169 
170  // Test saturation against other saturating counter
171  counter.reset();
172  value = initial_value;
173  counter <<= other;
174  value <<= other;
175  ASSERT_EQ(counter, value);
176  counter <<= saturated_counter;
177  value = max_value;
178  ASSERT_EQ(counter, max_value);
179 
180  // Test zeroing against other saturating counter
181  counter >>= other;
182  value >>= other;
183  ASSERT_EQ(counter, value);
184  counter >>= saturated_counter;
185  ASSERT_EQ(counter, 0);
186 
187  // Make sure the counters cannot be shifted by negative numbers, since
188  // that is undefined behaviour
189  ASSERT_DEATH(counter >>= -1, "");
190  ASSERT_DEATH(counter <<= -1, "");
191 }
192 
196 TEST(SatCounterTest, PrePostOperators)
197 {
198  const unsigned bits = 3;
199  const unsigned max_value = (1 << bits) - 1;
200  SatCounter counter_pre(bits);
201  SatCounter counter_post(bits);
202 
203  for (int i = 0; i < 2*max_value; i++) {
204  counter_post++;
205  SatCounter value_pre = ++counter_pre;
206  ASSERT_EQ(counter_post, value_pre);
207  }
208 
209  ASSERT_EQ(counter_pre, max_value);
210  ASSERT_EQ(counter_post, max_value);
211 
212  for (int i = 0; i < 2*max_value; i++) {
213  counter_post--;
214  SatCounter value_pre = --counter_pre;
215  ASSERT_EQ(counter_post, value_pre);
216  }
217 
218  ASSERT_EQ(counter_pre, 0);
219  ASSERT_EQ(counter_post, 0);
220 }
221 
225 TEST(SatCounterTest, CopyMove)
226 {
227  const unsigned bits = 3;
228  const unsigned max_value = (1 << bits) - 1;
229  const unsigned initial_value = 1;
230  SatCounter counter(bits, initial_value);
231  SatCounter deep_copy(1);
232  SatCounter counter_copy(2);
233 
234  // Increase counter value so that we can check if the inner counter is
235  // being copied
236  counter++;
237 
238  // Copy counter using both the copy constructor and the copy assignment
239  SatCounter counter_copy_constructor(counter);
240  deep_copy = counter_copy = counter;
241  ASSERT_EQ(counter_copy_constructor, initial_value + 1);
242  ASSERT_EQ(counter_copy, initial_value + 1);
243  ASSERT_EQ(deep_copy, initial_value + 1);
244 
245  // Make sure max value is the same for all of them, and that modifying
246  // the copies does not modify the original
247  for (int i = 0; i < 2*max_value; i++) {
248  counter_copy_constructor++;
249  counter_copy++;
250  deep_copy++;
251  }
252  ASSERT_EQ(counter, initial_value + 1);
253  ASSERT_EQ(counter_copy_constructor, max_value);
254  ASSERT_EQ(counter_copy, max_value);
255  ASSERT_EQ(deep_copy, max_value);
256 
257  // Make sure initial value is the same for all of them
258  counter_copy_constructor.reset();
259  counter_copy.reset();
260  deep_copy.reset();
261  ASSERT_EQ(counter_copy_constructor, initial_value);
262  ASSERT_EQ(counter_copy, initial_value);
263  ASSERT_EQ(deep_copy, initial_value);
264 
265  // Now check move
266  SatCounter counter_move_constructor(std::move(counter));
267  ASSERT_EQ(counter, 0);
268  ASSERT_EQ(counter_move_constructor, initial_value + 1);
269 
270  SatCounter counter_move(bits);
271  counter_move = std::move(counter_move_constructor);
272  ASSERT_EQ(counter_move_constructor, 0);
273  ASSERT_EQ(counter_move, initial_value + 1);
274 }
275 
279 TEST(SatCounterTest, AddSubAssignment)
280 {
281  const unsigned bits = 3;
282  const unsigned max_value = (1 << bits) - 1;
283  SatCounter counter(bits);
284  SatCounter other(bits, 2);
285  SatCounter saturated_counter(bits, max_value);
286  int value = 0;
287 
288  // Test add-assignment for a few random values and then saturate
289  counter += 2;
290  value += 2;
291  ASSERT_EQ(counter, value);
292  counter += 3;
293  value += 3;
294  ASSERT_EQ(counter, value);
295  counter += max_value;
296  value = max_value;
297  ASSERT_EQ(counter, value);
298 
299  // Test subtract-assignment for a few random values until back to zero
300  counter -= 2;
301  value -= 2;
302  ASSERT_EQ(counter, value);
303  counter -= 3;
304  value -= 3;
305  ASSERT_EQ(counter, value);
306  counter -= max_value;
307  value = 0;
308  ASSERT_EQ(counter, value);
309 
310  // Test add-assignment of other saturating counter
311  counter += other;
312  value += other;
313  ASSERT_EQ(counter, value);
314  counter += saturated_counter;
315  value = max_value;
316  ASSERT_EQ(counter, saturated_counter);
317 
318  // Test subtract-assignment of other saturating counter
319  counter -= other;
320  value -= other;
321  ASSERT_EQ(counter, value);
322  counter -= saturated_counter;
323  ASSERT_EQ(counter, 0);
324 }
325 
329 TEST(SatCounterTest, NegativeAddSubAssignment)
330 {
331  const unsigned bits = 3;
332  const unsigned max_value = (1 << bits) - 1;
333  SatCounter counter(bits, max_value);
334  int value = max_value;
335 
336  // Test add-assignment for a few negative values until zero is reached
337  counter += -2;
338  value += -2;
339  ASSERT_EQ(counter, value);
340  counter += -3;
341  value += -3;
342  ASSERT_EQ(counter, value);
343  counter += (int)-max_value;
344  value = 0;
345  ASSERT_EQ(counter, value);
346 
347  // Test subtract-assignment for a few negative values until saturation
348  counter -= -2;
349  value -= -2;
350  ASSERT_EQ(counter, value);
351  counter -= -3;
352  value -= -3;
353  ASSERT_EQ(counter, value);
354  counter -= (int)-max_value;
355  value = max_value;
356  ASSERT_EQ(counter, value);
357 }
358 
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:237
Implements an n bit saturating counter and provides methods to increment, decrement, and read it.
Definition: sat_counter.hh:54
void reset()
Reset the counter to its initial value.
Definition: sat_counter.hh:228
uint8_t saturate()
Saturate the counter.
Definition: sat_counter.hh:251
bool isSaturated() const
Whether the counter has achieved its maximum value or not.
Definition: sat_counter.hh:244
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:71

Generated on Thu May 28 2020 16:21:29 for gem5 by doxygen 1.8.13