fa36e7d5604e21c8ffa557cdf99588cdebe9fbe2
This class had been trying to keep all indices within the modulus of the queue size, and to use all elements in the underlying storage by making the empty and full conditions alias, differentiated by a bool. To keep track of the difference between a storage location on one trip around the queue vs other times around, ie an alias once the indices had wrapped, it also keep track of a "round" value in both the queue itself, and any iterators it created. All this bookkeeping significantly complicated the data structure. Instead, this change modifies it to keep track of a monotonically increasing index which is wrapped at the time it's used. Only the head index and current size need to be tracked in the queue itself, and only a pointer to the queue and an index need to be tracked in the iterators. Theoretically, it's possible that this value could overflow eventually since it increases forever, unlike before where the index wrapped and was never larger than the queue's capacity. In practice, the type of the index was changed from a uint32_t to a size_t, probably a 64 bit value in modern systems, which will hold much larger values. Also, the round counter and the index values together acted like a smaller than 64 bit value anyway, since the round counter would overflow after 2^32 times around a less than 2^32 entry queue. One minor interface difference is that the head() and tail() values returned by the queue are no longer pre-wrapped to be modulo the queue's capacity. As long as consumers don't try to be overly clever and feed in fixed values, do their own bounds checking, etc., something that would be cumbersome considering the wrapping nature of the structure, this shouldn't be an issue. Also, since external consumers no longer need to worry about wrapping, since only one of them was used in only one place, and because they weren't even marked as part of the interface, the modulo helper functions have been eliminated from the queue. If other code wants to perform modulo arithmetic for some reason (which the queue no longer requires) they can accomplish basically the same thing in basically the same amount of code using normal math. Also, rather than inherit from std::vector, this change makes the vector internal to the queue. That prevents methods of the vector that aren't aware of the circular nature of the structure from leaking out if they're not overridden or otherwise proactively blocked. On top of simplifying the implementation, this also makes it perform *slightly* better. To measure that, I ran the following command: $ time build/ARM/base/circular_queue.test.opt --gtest_repeat=100000 > /dev/null and found a few percent improvement in total run time. While this difference was small and not measured against realistic usage of the data structure, it was still measurable, and at minimum doesn't seem to have hurt performance. Change-Id: Ic2baa28de135be7086fa94579bbec451d69b3b15 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38478 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This is the gem5 simulator. The main website can be found at http://www.gem5.org A good starting point is http://www.gem5.org/about, and for more information about building the simulator and getting started please see http://www.gem5.org/documentation and http://www.gem5.org/documentation/learning_gem5/introduction. To build gem5, you will need the following software: g++ or clang, Python (gem5 links in the Python interpreter), SCons, SWIG, zlib, m4, and lastly protobuf if you want trace capture and playback support. Please see http://www.gem5.org/documentation/general_docs/building for more details concerning the minimum versions of the aforementioned tools. Once you have all dependencies resolved, type 'scons build/<ARCH>/gem5.opt' where ARCH is one of ARM, NULL, MIPS, POWER, SPARC, or X86. This will build an optimized version of the gem5 binary (gem5.opt) for the the specified architecture. See http://www.gem5.org/documentation/general_docs/building for more details and options. The basic source release includes these subdirectories: - configs: example simulation configuration scripts - ext: less-common external packages needed to build gem5 - src: source code of the gem5 simulator - system: source for some optional system software for simulated systems - tests: regression tests - util: useful utility programs and files To run full-system simulations, you will need compiled system firmware (console and PALcode for Alpha), kernel binaries and one or more disk images. If you have questions, please send mail to gem5-users@gem5.org Enjoy using gem5 and please share your modifications and extensions.
Description