Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAINT: avoid memcpy when i == j #8921

Merged
merged 1 commit into from
Apr 10, 2017
Merged

Conversation

rainwoodman
Copy link
Contributor

Valgrind complains about memcpy with overlapping address in mtrand.c
It happens when i == j in this loop.

Closer inspection the i == j iteration is not needed (it is a swap).
So, skip it and avoid depending on undefined behavior of memcpy.

related read:

https://sourceware.org/bugzilla/show_bug.cgi?id=12518

Valgrind complains about memcpy with overlapping address in mtrand.c
It happens when i == j in this loop.

Closer inspection the i == j iteration is not needed (it is a swap).
So, skip it and avoid depending on undefined behavior of memcpy.

related read:

https://sourceware.org/bugzilla/show_bug.cgi?id=12518
@@ -4828,6 +4828,7 @@ cdef class RandomState:
cdef npy_intp i, j
for i in reversed(range(1, n)):
j = rk_interval(i, self.internal_state)
if i == j : continue # i == j is not needed and memcpy is undefined.
Copy link
Contributor

Choose a reason for hiding this comment

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

just changing the rk_interval i to i -1 should be enough

Copy link
Contributor

Choose a reason for hiding this comment

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

no that is wrong, disregard

Copy link
Member

Choose a reason for hiding this comment

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

That would work, but would change the behaviour of a given random seed, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

worse it would mean a datapoint cannot stay in the same position after a shuffle which biases the result

@juliantaylor
Copy link
Contributor

Full overlap memcpy is actually fine.
I am a bit concerned if this impacts performance negatively.
If it does one could put a compile time constant size check before the condition.

@rainwoodman
Copy link
Contributor Author

small memcpy is also 'actually' fine (see the bz discussion), but since the spec says overlapped areas is undefined I think avoiding overlapping memcpy is the safest/portable approach; also rk_internal and the loop looked sufficiently complicated that adding an if shouldn't hurt the performance in any meaningful way?

@juliantaylor
Copy link
Contributor

I don't really like changing the generated code to silence a non-issue, too bad we can't use memmove as older gccs won't inline that.
But then it will probably cost more time going over this the next time than the combined cost of the few extra cycles.

@juliantaylor juliantaylor merged commit c0ab544 into numpy:master Apr 10, 2017
@juliantaylor
Copy link
Contributor

uhm dumb question to ask after pressing the button, but where exactly is the overlap in this code? memcpy is done into a temporary buffer here.
what code causes the valgrind error?

@juliantaylor
Copy link
Contributor

nevermind I see it ... my valgrind version just does not care about full overlap anymore.
I should just go to bed ._.

@rainwoodman rainwoodman deleted the memcpy branch April 11, 2017 00:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants