GeezerVison is showing github.com — gh-112050: Make collections.deque thread-safe in free-threaded builds by mpage · Pull Request #113830 · python/cpython
Conversation
mpage
commented
Jan 8, 2024
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
This uses critical sections to make deque methods that operate on mutable state thread-safe when the GIL is disabled. This is mostly accomplished by using the @critical_section clinic directive, though there are a few places where this was not possible and critical sections had to be manually acquired/released.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
itamaro and erlend-aasland reacted with rocket emoji
Convert most methods on collections.deque to use clinic. This will
allow us to use clinic's `@critical_section` directive when making
deques thread-safe for `--gil-disabled`, simplifying the implementation.
Clear is used only by the GC; no other threads are running.
I'll get some benchmark numbers in a bit.
Great; let's wait with landing this until we've got those.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
@erlend-aasland Here are some benchmark numbers using the default -O3. Let me know if you'd like me to run others. The only substantive change in this PR for default builds is to len, where we're now using an atomic load. I would expect that to be slower, though the benchmark numbers don't appear to confirm that assumption. If we're concerned about a slowdown there we could consider using an ifdef to limit the atomic load to only free-threaded builds.
len
I would expect a slowdown due to the use of atomics, but the data doesn't appear to support that.
This PR:
> ./python -m timeit -s "import collections; d = collections.deque(list(range(100)))" "len(d)"
10000000 loops, best of 5: 21.2 nsec per loop
main:
> ./python -m timeit -s "import collections; d = collections.deque(list(range(100)))" "len(d)"
10000000 loops, best of 5: 20.8 nsec per loop
__init__
This should be representative of methods that were annotated with the @critical_section directive. I wouldn't expect any performance change here; the generated acquire/release pair should be a no-op.
This PR:
> ./python -m timeit -s "import collections; L = list(range(100))" "collections.deque(L, 50)"
500000 loops, best of 5: 733 nsec per loop
> ./python -m timeit -s "import collections; L = list(range(100))" "collections.deque(L)"
500000 loops, best of 5: 769 nsec per loop
Main:
> ./python -m timeit -s "import collections; L = list(range(100))" "collections.deque(L, 50)"
500000 loops, best of 5: 731 nsec per loop
> ./python -m timeit -s "import collections; L = list(range(100))" "collections.deque(L)"
500000 loops, best of 5: 746 nsec per loop
contains
This should be representative of methods that had critical sections added manually. In the case of contains, that split the function into two. I wouldn't expect any performance change here in default builds. The compiler should still be able to fully optimize the refactored code.
This PR:
> ./python -m timeit -s "import collections; L = list(range(100))" "50 in L"
500000 loops, best of 5: 512 nsec per loop
> ./python -m timeit -s "import collections; L = list(range(100))" "1 in L"
10000000 loops, best of 5: 29.6 nsec per loop
> ./python -m timeit -s "import collections; L = list(range(100))" "100 in L"
500000 loops, best of 5: 1.02 usec per loop
main:
> ./python -m timeit -s "import collections; L = list(range(100))" "50 in L"
500000 loops, best of 5: 520 nsec per loop
> ./python -m timeit -s "import collections; L = list(range(100))" "1 in L"
10000000 loops, best of 5: 30.2 nsec per loop
> ./python -m timeit -s "import collections; L = list(range(100))" "100 in L"
200000 loops, best of 5: 1 usec per loop
>
|
erlend-aasland reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
|
@erlend-aasland - I think everything is addressed now. Would you please have another look?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
mpage reacted with heart emoji
|
I'm inclined to run the buildbots on this; Thomas is cooking up the release right now, so we really don't want one of the bots to turn red right now.
|
colesbury reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
🤖 New build scheduled with the buildbot fleet by @erlend-aasland for commit 6ffad44 🤖
If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
@erlend-aasland - Just noticed one last place where we want to use the macro wrapper. Would you please kick off another buildbot run. Sorry for the churn.
|
erlend-aasland reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
@erlend-aasland - Just noticed one last place where we want to use the macro wrapper. Would you please kick off another buildbot run. Sorry for the churn.
You should be able to trigger the buildbot run yourself, now you're a triager! :)
|
erlend-aasland reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
🤖 New build scheduled with the buildbot fleet by @mpage for commit fa7e8a8 🤖
If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
You should be able to trigger the buildbot run yourself, now you're a triager! :)
Oho - I'm drunk with power now! :P
|
erlend-aasland reacted with laugh emoji
AlexWaygood reacted with rocket emoji
All reactions
-
😄
1 reaction
-
🚀
1 reaction
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
corona10
corona10 approved these changes
rhettinger
Awaiting requested review from rhettinger
rhettinger is a code owner
Uh oh!
There was an error while loading. Please reload this page.
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|