Skip to content

fix erase_if method - #17101

Merged
kd-11 merged 2 commits into
RPCS3:masterfrom
digant73:fix_erase_if
Apr 26, 2025
Merged

kd-11 merged 2 commits into
RPCS3:masterfrom
digant73:fix_erase_if

Conversation

@digant73

@digant73 digant73 commented Apr 26, 2025 •

Copy link
Copy Markdown
Contributor

Fixes made by #17040 highlighted a further bug in erase_if method that should be fixed now. Probably more than the listed bug reports below were affected by the bug.

fixes #17098
should fix #17043

Comment thread rpcs3/Emu/RSX/Common/simple_array.hpp Outdated
// Move item to the end of the list and shrink by 1
std::memcpy(ptr, last, sizeof(Ty));
last = _data + (--_size);
last = _data + (--_size - 1); // set new last

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still wrong due to the swapped value not being evaluated. I need to fix this properly.

@digant73 digant73 Apr 26, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I also thought that the logic was overall not correct. The swapped ptr <> last is not tested (ptr will be increased in the for cycle and not tested).
Ok waiting for your fix and I will close this PR

@digant73 digant73 Apr 26, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if scanning/swapping order is not important then the following code (iterating from last to fist) should be ok:

			for (auto last = _data + (_size - 1), ptr = last; ptr >= _data; ptr--)
			{
				if (predicate(*ptr))
				{
					ret = true;

					if (ptr != last) // If not last
					{
						// Move last item into current one
						std::memcpy(ptr, last, sizeof(Ty));
					}

					// Pop last entry from list and set new last item
					_size--;
					last--;
				}
			}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still wrong, the deleted item is not removed. Swapping is important for single-pass filter alogrithms to avoid backtracking but I botched it this time and we don't have unit tests to catch these things.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#17102 fixes this properly. I also wrote the test for it in case you want to toy around with it: https://godbolt.org/z/4745MGT6z

@digant73 digant73 Apr 26, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I saw https://godbolt.org/z/4745MGT6z. Items are properly removed also with my code but of course the scanning from last to first produces same values but with different order. If order was not important then my code seems faster (a maximum of _size iterations with less code).
Also for a typical list with many items my if (ptr != last) ) statement is basically always satisfied while your if (ptr == last) is at maximum only one time satisfied incurring in some performance drop.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understood the missing removal, it seems there, but ok I see you provided the PR, so closing this

My fault for not testing this thoroughly, I missed the reversed direction of the scan.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed my changes as a reminder in case they will be ok.
I also thought if the items removed from the list are object types needing to be destroyed (e.g. release allocated pointers etc.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple array is stricly for POD types. This is enforced by the template.
Now for the impl, yours is fine so I'll merge to give credit, but I absolutely despise reversed loops unless I have no other choice (debugging requires inverting logic in the head which is not easy) so I will also merge my PR after to replace it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem at all. Not interested to credits etc.. Any solution fixing bugs is ok for me. I simply pushed my last changes just as reminder for myself before (sooner or later) I will permanently delete this PR from my repo.

@AniLeo
AniLeo marked this pull request as draft April 26, 2025 15:44
@Megamouse Megamouse added the RSX label Apr 26, 2025
@kd-11
kd-11 marked this pull request as ready for review April 26, 2025 18:13
@kd-11
kd-11 merged commit d7ef5a8 into RPCS3:master Apr 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Regression] Resident Evil Operation Raccoon City [Regression] Infamous 2

3 participants