bpo-40521: Make dict free lists per-interpreter#20645
Conversation
|
After tuple (commit 69ac6e5) and list (commit 88ec919) and others types (see bpo-40521), it's now the turn of dict to get its free lists moved to PyInterpreterState! FYI when I measured the tuple PR overhead, it was around 1 ns (and create a tuple of 1 item is around 20 ns): see PR #20247. |
Sorry, something went wrong.
|
With this PR, all free lists cleared by gc.collect() are per-interpreter. |
Sorry, something went wrong.
|
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. |
Sorry, something went wrong.
|
@vstinner Would you benchmark without freelist too? |
Sorry, something went wrong.
Here you have:
Disabling the free list adds +7.1 ns per |
Sorry, something went wrong.
|
TODO: implement commit bcb1983 for dict free lists. See https://bugs.python.org/issue40887 for the context. |
Sorry, something went wrong.
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. |
Sorry, something went wrong.
methane
left a comment
There was a problem hiding this comment.
The discussion in the ML didn't go anywhere.
I'm OK to merge this.
Sorry, something went wrong.
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... |
Sorry, something went wrong.
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