gem5  v20.1.0.0
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. As these tests depend on asserts failing,
189  // these tests are only functional if `TRACING_ON == 1`, when gem5 is
190  // compiled as `debug` or `opt`.
191  #if TRACING_ON
192  ASSERT_DEATH(counter >>= -1, "");
193  ASSERT_DEATH(counter <<= -1, "");
194  #endif
195 }
196 
200 TEST(SatCounterTest, PrePostOperators)
201 {
202  const unsigned bits = 3;
203  const unsigned max_value = (1 << bits) - 1;
204  SatCounter counter_pre(bits);
205  SatCounter counter_post(bits);
206 
207  for (int i = 0; i < 2*max_value; i++) {
208  counter_post++;
209  SatCounter value_pre = ++counter_pre;
210  ASSERT_EQ(counter_post, value_pre);
211  }
212 
213  ASSERT_EQ(counter_pre, max_value);
214  ASSERT_EQ(counter_post, max_value);
215 
216  for (int i = 0; i < 2*max_value; i++) {
217  counter_post--;
218  SatCounter value_pre = --counter_pre;
219  ASSERT_EQ(counter_post, value_pre);
220  }
221 
222  ASSERT_EQ(counter_pre, 0);
223  ASSERT_EQ(counter_post, 0);
224 }
225 
229 TEST(SatCounterTest, CopyMove)
230 {
231  const unsigned bits = 3;
232  const unsigned max_value = (1 << bits) - 1;
233  const unsigned initial_value = 1;
234  SatCounter counter(bits, initial_value);
235  SatCounter deep_copy(1);
236  SatCounter counter_copy(2);
237 
238  // Increase counter value so that we can check if the inner counter is
239  // being copied
240  counter++;
241 
242  // Copy counter using both the copy constructor and the copy assignment
243  SatCounter counter_copy_constructor(counter);
244  deep_copy = counter_copy = counter;
245  ASSERT_EQ(counter_copy_constructor, initial_value + 1);
246  ASSERT_EQ(counter_copy, initial_value + 1);
247  ASSERT_EQ(deep_copy, initial_value + 1);
248 
249  // Make sure max value is the same for all of them, and that modifying
250  // the copies does not modify the original
251  for (int i = 0; i < 2*max_value; i++) {
252  counter_copy_constructor++;
253  counter_copy++;
254  deep_copy++;
255  }
256  ASSERT_EQ(counter, initial_value + 1);
257  ASSERT_EQ(counter_copy_constructor, max_value);
258  ASSERT_EQ(counter_copy, max_value);
259  ASSERT_EQ(deep_copy, max_value);
260 
261  // Make sure initial value is the same for all of them
262  counter_copy_constructor.reset();
263  counter_copy.reset();
264  deep_copy.reset();
265  ASSERT_EQ(counter_copy_constructor, initial_value);
266  ASSERT_EQ(counter_copy, initial_value);
267  ASSERT_EQ(deep_copy, initial_value);
268 
269  // Now check move
270  SatCounter counter_move_constructor(std::move(counter));
271  ASSERT_EQ(counter, 0);
272  ASSERT_EQ(counter_move_constructor, initial_value + 1);
273 
274  SatCounter counter_move(bits);
275  counter_move = std::move(counter_move_constructor);
276  ASSERT_EQ(counter_move_constructor, 0);
277  ASSERT_EQ(counter_move, initial_value + 1);
278 }
279 
283 TEST(SatCounterTest, AddSubAssignment)
284 {
285  const unsigned bits = 3;
286  const unsigned max_value = (1 << bits) - 1;
287  SatCounter counter(bits);
288  SatCounter other(bits, 2);
289  SatCounter saturated_counter(bits, max_value);
290  int value = 0;
291 
292  // Test add-assignment for a few random values and then saturate
293  counter += 2;
294  value += 2;
295  ASSERT_EQ(counter, value);
296  counter += 3;
297  value += 3;
298  ASSERT_EQ(counter, value);
299  counter += max_value;
300  value = max_value;
301  ASSERT_EQ(counter, value);
302 
303  // Test subtract-assignment for a few random values until back to zero
304  counter -= 2;
305  value -= 2;
306  ASSERT_EQ(counter, value);
307  counter -= 3;
308  value -= 3;
309  ASSERT_EQ(counter, value);
310  counter -= max_value;
311  value = 0;
312  ASSERT_EQ(counter, value);
313 
314  // Test add-assignment of other saturating counter
315  counter += other;
316  value += other;
317  ASSERT_EQ(counter, value);
318  counter += saturated_counter;
319  value = max_value;
320  ASSERT_EQ(counter, saturated_counter);
321 
322  // Test subtract-assignment of other saturating counter
323  counter -= other;
324  value -= other;
325  ASSERT_EQ(counter, value);
326  counter -= saturated_counter;
327  ASSERT_EQ(counter, 0);
328 }
329 
333 TEST(SatCounterTest, NegativeAddSubAssignment)
334 {
335  const unsigned bits = 3;
336  const unsigned max_value = (1 << bits) - 1;
337  SatCounter counter(bits, max_value);
338  int value = max_value;
339 
340  // Test add-assignment for a few negative values until zero is reached
341  counter += -2;
342  value += -2;
343  ASSERT_EQ(counter, value);
344  counter += -3;
345  value += -3;
346  ASSERT_EQ(counter, value);
347  counter += (int)-max_value;
348  value = 0;
349  ASSERT_EQ(counter, value);
350 
351  // Test subtract-assignment for a few negative values until saturation
352  counter -= -2;
353  value -= -2;
354  ASSERT_EQ(counter, value);
355  counter -= -3;
356  value -= -3;
357  ASSERT_EQ(counter, value);
358  counter -= (int)-max_value;
359  value = max_value;
360  ASSERT_EQ(counter, value);
361 }
362 
SatCounter::reset
void reset()
Reset the counter to its initial value.
Definition: sat_counter.hh:286
TEST
TEST(SatCounterTest, MaximumValue)
Test if the maximum value is indeed the maximum value reachable.
Definition: sat_counter.test.cc:39
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
sat_counter.hh
SatCounter::saturate
uint8_t saturate()
Saturate the counter.
Definition: sat_counter.hh:315
SatCounter::calcSaturation
double calcSaturation() const
Calculate saturation percentile of the current counter's value with regard to its maximum possible va...
Definition: sat_counter.hh:297
SatCounter::isSaturated
bool isSaturated() const
Whether the counter has achieved its maximum value or not.
Definition: sat_counter.hh:306
SatCounter
Implements an n bit saturating counter and provides methods to increment, decrement,...
Definition: sat_counter.hh:54
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17