gh-127716: make memoryview thread-safe in free-threaded build - #156248
Open
nascheme wants to merge 7 commits into
Open
gh-127716: make memoryview thread-safe in free-threaded build#156248nascheme wants to merge 7 commits into
nascheme wants to merge 7 commits into
Conversation
Documentation build overview
21 files changed ·
|
Contributor
Co-authored-by: ayaangazali <ayaangazali.work@gmail.com> Co-authored-by: Lu Xiaowei <weixlu420302@gmail.com>
nascheme
force-pushed
the
gh-127716-memoryview-thread-safe
branch
from
August 25, 2026 16:24
4269e2d to
8fa2daf
Compare
* The CHECK_* macros can return. Restructure code so that unpin is always done for toreadonly(). * Use atomic load for asserts on `exports`.
Speed it up (less iterations, rounds and threads). Rename confusing assert_exporter_free() method to ensure_exporter_free().
…yview-thread-safe
* Add comment to CAS while loop, yielding is unnecessary. * Use "relaxed" memory ordering, seq-cst is overkill.
…yview-thread-safe
We only need the "while" loop if we are setting multiple flag bits concurrently. That's not needed, we only set RELEASED. So, restructure code, no while loop needed and someone can't accidently call the function in the wrong way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Note: this PR was developed with assistance from LLMs, Claude Opus/Fable and GPT 5.6 Sol.
This incorporates changes from gh-155882 and gh-154770. It goes further and ensures the underlying buffer remains "pinned" if a thread releases the memory view while other threads have in-flight operations on it.
Performance testing results are below. The goal is negligible slowdown for the GIL-enabled build (achieved). Also, we want negligible slowdown in the un-contended free-threaded case (also achieved). Unfortunately, multi-threaded scaling with a shared
memoryviewobject is terrible.I explored various ways of improving the scaling (QSBR, RCU, hazard pointers) but I think other options are too complex in terms of implementation or have other critical problems. If you want multiple threads operating on the same underlying "mbuf", a good way to do it is to create a thread-local
memoryviewcopy. You need to do this from the orginal "exporter" object, not the existingmemoryviewobject. I have an additional change that adds a.reexport()method that does this, which is probably handly.Single-thread performance
Times are nanoseconds per operation (lower is better), minus loop overhead; iteration is
nanoseconds per element. "base" is before this PR and "patched" is after.
Results from Intel i7-14700K
getitemsetitemformatslicecasttobytes_16memoryview_of_viewstruct.unpack_fromBytesIO.readintoBytesIO.writeResults from Macbook M3 Pro.
getitemsetitemformatslicecasttobytes_16memoryview_of_viewunpack_frombytesio_writebytesio_readintoFree-threaded scaling
Throughput is millions of operations per second (higher is better). For iteration, one yielded
element is one operation. Base has no
reexport(), so that workload has apatched row only; compare it against the
separate views of one exporterrows.Results from Intel i7-14700K
mv[0]mv[0]mv[0]reexport()views,mv[0]mv[0]tobytes()4 KiBstruct.unpack_fromResults from Macbook M3 Pro. Note that this CPU has 6 P-cores and 6 E-cores.
mv[0]mv[0]mv[0]reexport()views,mv[0]mv[0]tobytes()4 KiBstruct.unpack_fromAnything that shares one managed buffer contends (shared
mbuf->exportscache line).