EmuCR Feeds
Email Us

EmuCR:OpenMSX OpenMSX Git (2015/09/18) is complie. OpenMSX is an open source MSX emulator which is free according to the Debian Free Software Guidelines, available under the GNU General Public License.For copyright reasons the emulator cannot be distributed with original BIOS ROM images. OpenMSX includes C-BIOS a minimal implementation of the MSX BIOS, allowing to play quite some games without the need to have an original MSX BIOS ROM image. You can also use your own BIOS ROM image if you please.

OpenMSX Git Changelog:
* [10/10] small cleanup: use find_if_unguarded
Use the existing find_if_unguarded() utility instead of manually implementing the
same loop.
* [9/10] Tweak removing 'garbage boards'
For some reason, in the Reactor, code we postpone deleting of MSXMotherBoard's
(see 1aa4ba50 for details). The do this we put the to-be-deleted board in the
garbageBoards vector and send a OPENMSX_DELETE_BOARD event. When that event
(eventually) gets handled we actually delete the board.
It is possible that multiple boards are scheduled to be deleted before the
DELETE_BOARD event handler gets executed. Before we made sure that each event
deletes the board for which it was scheduled. Though the exact order in which
the boards get deleted doesn't matter (as long as they all get deleted).
This patch takes advantage of this freedom and slightly optimizes this deletion
step: it's cheaper to remove the last element from a vector than the first
element.
* [8/10] Use move_pop_back() more
In an earlier patch in this series we optimized
v.erase(find_unguarded(v, e));
to
v.erase(rfind_unguarded(v, e));
In case the order of the elements in the vector doesn't matter we can optimize
it further to
move_pop_back(v, rfind_unguarded(v, e));
* [7/10] Convert existing patterns to move_pop_back()
We already had quite a few places in our code where we use the
move-then-pop-back stuff we introduced in the previous patch. This patch
converts (=simplifies) those locations to use the new move_pop_back() function.
Actually in some of those locations we swapped the to-be-removed element with
the last element instead of only moving the last element over the to-be-removed
element. That's (a little bit) more work than needed. So also fixed now.
* [6/10] Added move_pop_back() function
This utility removes an element from a vector by
- first moving the last element of the vector over the to-be-removed elememt
- then erase the last (now unused) position
In case the order of the elements in the vector doesn't matter, this is a
faster alternative compared to calling the vector::erase() method (because that
one has to shift all later elements to the front).
This patch only adds the new function but doesn't use it yet.
* [5/10] Use the new partition_copy_remove() function
In the implementation of the 'after' command (inside the AfterCommand class),
at one point we have a vector of registered commands and a predicate that tells
which of these commands should be processed. But before actually processing the
matching commands they should be removed from the original vector (because of
iterating-over-a-changing-vector stuff).
Before this patch we used the following solution:
- We partition the commands according to our predicate (using std::partition).
This moves the to-be processed commands to the back of the vector.
- We then move these element into a new vector, shrink the original vector,
and then loop over that new vector.
This has the following disadvantages:
- The to-be-processed commands are moved twice. Once to the back and then
again to a new vector. Though typically there's are only very few matching
commands, so this is a very minor point.
- Maybe more important is that the partition algorithm is not stable. Stable
in the STL-sense, so the relative order of the elements in both partitions
is not preserved. Maybe stability is not strictly required, but it's nice
to have a more predictable behavior of Tcl scripts. For example:
- 2 Tcl scripts register an after command for the same event
- Before this patch, when that event occurs, the order in which these two
commands get executed was not predictable. (It is deterministic, but it
could be influenced by various other stuff, e.g. other commands that get
registered or executed).
- After this patch the 2 command will get executed in the same order as
in which they were registered.
This patch replaces the partition-then-move step with the new
partition_copy_remove() function. This function:
- Also executes in O(N) time (just as the old solution).
- It performs the minimal number of move operations.
- It is stable (= it preserves order).
* [4/10] Added partition_copy_remove() utility function
This takes a range of elements and a predicate as input. It moves all elements
of the range that satisfy the predicate to a given output range and all
elements that don't satisfy the predicate are moved in-place to the front of
the original input range. See comments in code for more details.
This patch only adds the new function but doesn't use it yet.
* [3/10] Use rfind_(if_)unguarded()
Suppose we have a vector, we search an element using linear search (e.g.
because vector is unordered or very small) and we then erase that element.
Typical code to do this is:
auto it = find(begin(v), end(v), e);
if (it != end(v)) v.erase(it);
Or if we are sure the to-be-removed element is certainly present we can use
this faster variant:
v.erase(find_unguarded(v, e));
Now think about what's happening. We start at the front of the vector and walk
over all elements until we found the element we're interested in. Then we erase
that element, that means we shift all later elements one position to the front.
So this means that wherever the element was located (near the front, middle or
back) we always touch the memory locations for the whole vector.
Now let's make a small change to the example (literally only add 1 character):
v.erase(rfind_unguarded(v, e));
This also does a linear search, but it starts from the back instead of the
front. When we arrive at the element we again erase it by moving all later
elements one position to the front. But now we move elements that we've just
visited during the search, so they are almost guaranteed to be in the CPU's
L1-cache.
If we assume the elements are unordered and/or we search for a random element
there's no reason to prefer searching from front-to-back or from back-to-front.
However a pattern that often occurs in practice is that elements are
added/removed in a (more or less) FIFO order. So the to-be-removed element is
more likely to be located near the back of the vector. In that case starting
the search from the back has an additional advantage.
--
So this patch replaces all erase(find_unguarded(..)) patterns in our code with
erase(rfind_unguarded(..)).
* [2/10] Added rfind_unguarded and rfind_if_unguarded
These are like the existing utility functions find_unguarded() and
rfind_if_unguarded(), except that they search from back to front (iow a reverse
search).
This patch only adds the new functions but doesn't use them yet. That's
something for the next patch. See also that patch for why these functions are
useful.
* [1/10] Document sorting criteria (if any) for vectors
This might be the most important patch in this series even though it doesn't
make any actual code changes. It only adds some comments.
This patch documents for many of the std::vector variables we use whether the
elements they contain are kept in a particular order. And if so what the
sorting criteria is.
Later patches in this series tweak some of the operations we perform on vectors,
but some of these tweaks are only allowed if e.g. the order of the elements
doesn't matter.

Download: OpenMSX Git (2015/09/18) x86
Download: OpenMSX Git (2015/09/18) x64
Source: Here



Random Related Topic Refresh Related Topic

Random Related Topic Loading...

0 Comments

Post a Comment

Can't post a comment? Try This!