Up-to-date TODO list for per-interpreter GIL.
I'm moving the TODO, etc. to https://github.com/ericsnowcurrently/multi-core-python/wiki/0-The-Plan
Here's a rough TODO list, sort of in order (a lot can be done in parallel).
Note that most of these items fall out of Tools/c-analyzer/cpython/globals-to-fix.tsv. (Run ./python Tools/c-analyzer/table-file.py Tools/c-analyzer/cpython/globals-to-fix.tsv to get counts.)
(https://github.com/python/cpython/issues/84692)
Primary Tasks
- [x] analysis (summary)
- proposal: "A Per-Interpreter GIL"
- [x] initial python-dev discussion
- [x] clarify next steps with the steering council
- [x] write the proposal (PEP 684)
- [ ] accepted
- tooling (to identify global variables)
- [x] analyze requirements & make design
- [x] implement the tool (Tools/c-analyzer)
- [ ] re-enable CI check to prevent addition of more globals (may need fixes)
- resolve main blockers
- [ ] objects exposed in public C-API (solve with immortal objects)
- [ ] shared vs. per-interpreter allocators (solve with mimalloc)
- [ ] impact on extension maintainers (solve with docs, work with numpy)
- implementation
- prerequisites
- consolidate globals (#81057)
- [x] ... (move a bunch of stuff into
_PyRuntimeState) - [x] ... (statically init a bunch of global objects)
- [ ] (maybe?) move some state from
PyInterpreterStateto_PyRuntimeState - [ ] drop
_Py_IDENTIFIER()in extensions (or modify it to use a statically initialized str?)- [ ] Modules/_asynciomodule.c
- [ ] Modules/_ctypes/callbacks.c
- [ ] Modules/_ctypes/callproc.c
- [ ] Modules/_ctypes/_ctypes.c
- [ ] Modules/_ctypes/stgdict.c
- [ ] Modules/_cursesmodule.c
- [ ] Modules/_datetimemodule.c
- [ ] Modules/_elementtree.c
- [ ] Modules/_json.c
- [ ] Modules/ossaudiodev.c
- [ ] Modules/_testcapimodule.c
- [ ] Programs/_testembed.c
- [x] statically init latin-1 chars
- [ ] statically init currently cached str objects
- [ ] deal with PyArg_Parser (#90928, #82322, faster-cpython#281)
- [ ] pull remaining objects into
_PyRuntimeState - [ ] pull remaining state into
_PyRuntimeState
- [x] ... (move a bunch of stuff into
- prep for per-interpreter state
- [ ] solve per-interpreter state for core/builtin static types (e.g. dynamic lookup for some attrs)
- [ ] solve for extensions
- [ ] make some vars atomic?
- [ ] convert stdlib extensions to PEP 630 (see bpo-40077, PEP 687 & the SC discussion)
- add new C-API and implement runtime machinery
- [ ] ...
- move state (incl. GIL) to
PyInterpreterState- [ ] enforce restrictions on importing extensions...
- [ ] finally: move some state/objects to
PyInterpreterState - [ ] 💥 move the GIL to
PyInterpreterState💥
Solutions for Blockers
Immortal Objects:
- [x] analysis, design, and initial discussion (bpo-40255)
- [x] implement basic solution (gh-19474)
- [x] run benchmarks (incl. with all objects immortalized at end of runtime init)
- [ ] (maybe?) prepare a contingency plan for if we don't end up with immortal objects
- [x] write a proposal (PEP 683)
- [x] present at the language summit
- [x] enumerate other strategies for getting back to performance neutral
- [x] implement them
- [ ] PEP accepted
- [ ] merge implementation
mimalloc (thread-safe, performant allocator):
- [x] get mimalloc working as CPython's allocator (Christian: ...)
- [ ] add static analyzer support (ASAN, valgrind) (Daan)
- [ ] resolve problem with leaking large blocks (Daan/Christian)
- [ ] resolve PGO issues on Windows (Eric: contact MSVC team)
- [ ] merge the implementation
- [ ] sort out GIL guarantees for allocator API
Reduce Impact on Extension Maintainers:
- [ ] add docs (i.e. copy PEP 630)
- [ ] (probably) add some new C-API to solve pain points
- [ ] work with numpy, specifically, to add support for multiple interpreters
- [ ] work with cython
Secondary Tasks
- [ ] finish "c-analyzer.py data count"
- [ ] fix "c-analyzer.py data check" & add to CI
- [ ] statically init other immutables
- [ ] ...
Other Related Items
- PEP 554 (stdlib module to expose multiple interpreters)
- help numpy, cython, etc.
- PEP: add Public C-API as replacement for
_Py_IDENTIFIER()(@zooba's staticstr?) - "subinterpreters" project: https://github.com/orgs/python/projects/3/views/1
FYI, here's a recent breakdown of the remaining globals:
- core/builtins (651 total)
- 298 static types (incl. 130 exception types)
- 179 cached objects (e.g. str instances)
- 57 other objects
- 117 non-object (incl. 60 state)
- extension modules (605 total)
- 78 static types
- 317 cached objects (e.g. str instances)
- 145 other objects
- 65 non-object (incl. 29 state)
(the detailed breakdown)
./python Tools/c-analyzer/table-file.py Tools/c-analyzer/cpython/globals-to-fix.tsv
--------------------------------------------------
(365) global objects to fix in core code
119 static types
130 builtin exception types
9 singletons
(98) cached - initialized once
39 manually cached PyUnicodeObject
54 _PyArg_Parser (holds tuple of strings)
1 holds strings
4 other
(9) other
7 initialized once
2 state
--------------------------------------------------
(94) global non-objects to fix in core code
(29) initialized/set once
1 pre-allocated buffer
13 during init
15 lazy
(20) unlikely to change after init (or main thread)
11 through C-API
4 REPL
5 handling C argv
(45) state
15 allocator
2 pre-allocated memory
2 local buffer
2 linked list
24 other
--------------------------------------------------
(169) global objects to fix in builtin modules
22 modules
49 static types
(5) non-static types - initialized once
3 structseq types
2 exception types
(81) cached - initialized once
29 manually cached PyUnicodeOjbect
52 _PyArg_Parser
(12) other
6 initialized once
6 state
--------------------------------------------------
(23) global non-objects to fix in builtin modules
8 initialized once
15 state
--------------------------------------------------
(540) global objects to fix in extension modules
65 modules
78 static types
(34) non-static types - initialized once
3 structseq types
6 heap types
25 exception types
(317) cached - initialized once
18 _Py_IDENTIFIER (global)
149 _Py_IDENTIFIER (local)
1 _Py_static_string
12 manually cached PyUnicodeOjbect
124 _PyArg_Parser
13 other - during module init
(46) other
31 initialized once
15 state
--------------------------------------------------
(65) global non-objects to fix in extension modules
(36) initialized once
2 pre-allocated buffer
34 other
29 state
--------------------------------------------------
(total: 1256)
statically init latin-1 chars is done https://bugs.python.org/issue46881