-
-
Notifications
You must be signed in to change notification settings - Fork 31.3k
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
bpo-40521: Make dict free lists per-interpreter #20645
Conversation
With this PR, all free lists cleared by gc.collect() are per-interpreter. |
Before anyone asks, here is a microbenchmark on PyDict_New() to measure the overhead of this PR:
The PR adds +1.9 ns per PyDict_New() call. I used bench_dict.patch which is attached to https://bugs.python.org/issue40521. UPDATE: please notice that the std dev is around 1 ns which is close to the overhead. These microbenchmark are so small that it is really hard to get a precise measure of timings. |
@vstinner Would you benchmark without freelist too? |
Here you have:
Disabling the free list adds +7.1 ns per |
TODO: implement commit bcb1983 for dict free lists. See https://bugs.python.org/issue40887 for the context. |
Each interpreter now has its own dict free list: * Move dict free lists into PyInterpreterState. * Move PyDict_MAXFREELIST define to pycore_interp.h * Add _Py_dict_state structure. * Add tstate parameter to _PyDict_ClearFreeList() and _PyDict_Fini(). * In debug mode, ensure that the dict free lists are not used after _PyDict_Fini() is called. * Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS".
@methane: So, what do you think? I rebased my PR on top of the master branch.
Done. In debug mode, trying to use dict free lists after they are finalized now fails with an assertion error. |
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.
The discussion in the ML didn't go anywhere.
I'm OK to merge this.
Thanks @methane for the review! I'm still interested to attempt to reduce the overhead of this change. See my PR #20767 for example. But so I failed to find a method which has a significant impact on performance. Again, measuring performance of a function taking around 10 ns is really hard. The machine code changes depending on LTO and/or PGO build modes, compiler flags, etc. And sometimes it's faster, sometimes it's slower... |
Each interpreter now has its own dict free list: * Move dict free lists into PyInterpreterState. * Move PyDict_MAXFREELIST define to pycore_interp.h * Add _Py_dict_state structure. * Add tstate parameter to _PyDict_ClearFreeList() and _PyDict_Fini(). * In debug mode, ensure that the dict free lists are not used after _PyDict_Fini() is called. * Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS".
Each interpreter now has its own dict free list: * Move dict free lists into PyInterpreterState. * Move PyDict_MAXFREELIST define to pycore_interp.h * Add _Py_dict_state structure. * Add tstate parameter to _PyDict_ClearFreeList() and _PyDict_Fini(). * In debug mode, ensure that the dict free lists are not used after _PyDict_Fini() is called. * Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS".
Each interpreter now has its own dict free list:
_PyDict_Fini().
https://bugs.python.org/issue40521