How many orthogonal patchsets could this reasonably be broken into (and what would their interdependencies be)? #17
Replies: 1 comment
-
This is a difficult question to answer in general. I'm not sure how many logical patchsets there are, let alone their interdependencies. I'm in the process or rebasing and refactoring the changes into logical commits on the nogil-3.9 branch. Once I'm done, I'll have a better sense of how many logical commits there are. It's easier to answer the questions about specific features.
Yes, you can add mimalloc independently. There are changes to mimalloc necessary to support other features, though.
They do not require mimalloc. Immortalization is completely independent of the other features. Biased reference counting is almost independent of the other features, but it's convenient to have implemented the inter-thread signaling changes first. Deferred reference counting is more tricky. Doing it in a way that's actually useful requires substantial changes to the interpreter.
It requires mimalloc, but does not require the GIL changes. Currently, I've split the GC changes into three commits. First, I remove some features that will no longer be helpful without the GIL (gc: make the garbage collector non-generational). Second, I change it to use mimalloc instead of maintaining the GC linked list (gc: Traverese mimalloc heaps to find all objects.) Finally, I change the GC to use a stop-the-world mechanism ("Implement stop-the-world GC").
"typeobject: make method_cache thread-local". It's independent of the other changes, except that like many of the other features it depends on the new internal locking API ("Add mutexes and one-time notifications").
It effectively requires mimalloc (and some changes to mimalloc).
These are relatively simple and independent of the changes. "pystate: keep track of attached vs. detached state". The important part of this changes is the modification to _PyThreadState_Swap, which is called by the public thread state APIs.
The interpreter changes are dependent on many of the other changes, such as changes to "dict". The motivation is to efficiently implement deferred reference counting (for scalability) and be able to (re-)implement other interpreter optimizations in a thread-safe way (e.g. LOAD_GLOBAL caching). |
Beta Was this translation helpful? Give feedback.
-
I mean this less from a perspective of "pick and choose parts of the project" and more from the perspective of trying to understand how everything is logically holding together.
For example, unless I'm missing something mimalloc should be usable without any other changes. So a (fairly trivial) patchset could be to simply add that in as the default (or maybe required) allocator. Next you could start making use of mimalloc by changing the GC algorithms and/or the collection lookup procedure. Maybe this would allow you to move the GIL calls down the tree for the various collections making them more and more concurrent. Essentially what I'm trying to understand is which of these logically separate patchsets would be independent of one another and which would require other patchsets to already be in place. Hopefully my question makes sense.
Here are the separate pieces from your doc as well as my own ignorant musings:
Thanks for any clarity you can provide! This is all really great work!
Beta Was this translation helpful? Give feedback.
All reactions