|
| 1 | +PEP: 779 |
| 2 | +Title: Criteria for supported status for free-threaded Python |
| 3 | +Author: Thomas Wouters < [email protected]>, |
| 4 | + Matt Page <mpage at python.org>, |
| 5 | + Sam Gross <colesbury at gmail.com> |
| 6 | +Status: Draft |
| 7 | +Type: Standards Track |
| 8 | +Created: 03-Feb-2025 |
| 9 | +Python-Version: 3.14 |
| 10 | + |
| 11 | + |
| 12 | +Abstract |
| 13 | +======== |
| 14 | + |
| 15 | +The acceptance of :pep:`703` (Making the Global Interpreter Lock Optional in |
| 16 | +CPython), as `announced by the Steering Council |
| 17 | +<https://discuss.python.org/t/pep-703-making-the-global-interpreter-lock-optional-in-cpython-acceptance/37075>`__, |
| 18 | +describes three phases of development for the work to remove the Global |
| 19 | +Interpreter Lock. Phase I started early in the development of Python 3.13, |
| 20 | +and includes making the free-threaded (GIL-less) Python build available but |
| 21 | +explicitly *experimental*. Phase II would make the free-threaded build |
| 22 | +officially supported but still optional, and phase III would make the |
| 23 | +free-threaded build the default. Because of the number of unknowns at the |
| 24 | +time, the criteria for moving to the next phase were left deliberately vague |
| 25 | +at the time. This PEP establishes clear expectations and requirements for |
| 26 | +moving to Phase II, making the free-threaded Python build officially |
| 27 | +supported. |
| 28 | + |
| 29 | +.. note:: |
| 30 | + |
| 31 | + Eagle-eyed readers may have noticed an overlap in authors of this PEP and |
| 32 | + the Steering Council at the time of PEP 703 acceptance. The SC makeup has |
| 33 | + since changed, but just to make it explicit: this PEP as proposed, while |
| 34 | + based on criteria set forth by the SC, does not come from the Steering |
| 35 | + Council itself. |
| 36 | + |
| 37 | +Motivation |
| 38 | +========== |
| 39 | + |
| 40 | +Whether to move forward with :pep:`703` (as well as ultimately making it the |
| 41 | +default) is a question of whether the costs outweigh the benefits. Making |
| 42 | +free-threaded Python an officially supported build is important to signal |
| 43 | +that we're now at a stage where the design is finalised, the APIs are usable |
| 44 | +and stable, and we're satisfied the performance and complexity cost is not |
| 45 | +prohibitive. |
| 46 | + |
| 47 | +Moving to the "officially supported" stage is an important step towards |
| 48 | +making free-threaded Python the default build, and eventually the only one. |
| 49 | +Before we can decide we're ready to make it the default, we need a much |
| 50 | +better picture of the costs and the benefits, and we can only get there if |
| 51 | +more of the Python ecosystem starts supporting free-threaded Python. We |
| 52 | +currently have enough packages and tools supporting :pep:`703` that it's |
| 53 | +clear we're on the right path, but not enough to make the final decision. In |
| 54 | +addition to giving the Python community time to make the changes necessary |
| 55 | +to support free-threaded Python, we expect to use phase II to show clear |
| 56 | +benefits in real-world applications, as well as clearly define the cost in |
| 57 | +terms of performance, support burden, and ecosystem complexity. |
| 58 | + |
| 59 | +Rationale |
| 60 | +========= |
| 61 | + |
| 62 | +In order for PEP 703 to be acceptable it should be desirable, stable, |
| 63 | +maintainable, performant (in CPU and memory), and ideally it should have |
| 64 | +Stable ABI so the same wheels can be used for free-threaded and with-GIL |
| 65 | +builds. |
| 66 | + |
| 67 | +- Desirability: from various experiments it's very clear free-threaded |
| 68 | + Python has tremendous potential benefit. It's not a simple drop-in |
| 69 | + solution -- some code will have to be redesigned to make the most of the |
| 70 | + new capability, as well as avoid performance pitfalls -- but it can |
| 71 | + achieve higher performance, significantly lower latency and new |
| 72 | + thread-based functionality when embraced. |
| 73 | + |
| 74 | +- Stability: the majority of the new API design is in 3.13, and is being |
| 75 | + successfully used to support free-threaded Python in a number of |
| 76 | + third-party packages (see for example |
| 77 | + https://py-free-threading.github.io/tracking/). There's been some more |
| 78 | + development in 3.14 to add more convenience functions, and to replace |
| 79 | + APIs that previously relied on the GIL for thread-safety, but we have not |
| 80 | + had to break the 3.13 APIs for free-threaded Python. |
| 81 | + |
| 82 | +- Maintainability: the majority of :pep:`703`'s design is relatively |
| 83 | + simple, with most complexity hidden away behind CPython's existing C |
| 84 | + APIs. The implementation details of, for example, lockless list and dict |
| 85 | + APIs, `which rely on QSBR <https://github.com/python/cpython/issues/115103>`_, |
| 86 | + and `deadlock-avoiding critical sections <https://github.com/python/cpython/issues/115103>`_, |
| 87 | + may be complex and difficult to get right, but gives us easy to use APIs |
| 88 | + without too many pitfalls. Making more of CPython free-threading-safe is |
| 89 | + a relatively simple process, although we do probably need more |
| 90 | + documentation on the basic guarantees the new APIs provide |
| 91 | + (https://github.com/python/cpython/issues/128642). |
| 92 | + |
| 93 | +- Performance: the performance penalty on linear performance, comparing a |
| 94 | + free-threaded build against a with-GIL build, as measured by the |
| 95 | + pyperformance benchmarks (for example as run by `Microsoft's Faster |
| 96 | + CPython team <https://github.com/faster-cpython/benchmarking-public/>`_, |
| 97 | + or `Meta's Python Runtime team <https://github.com/facebookexperimental/free-threading-benchmarking>`_), |
| 98 | + is currently around 10% (except on macOS, where it's more like 3%). We |
| 99 | + have a few more PRs in flight that should get us comfortably below 10% on |
| 100 | + Linux and Windows. |
| 101 | + |
| 102 | +- Memory use. Exact numbers vary because of the different gc module |
| 103 | + implementation, but free-threaded Python currently sees about 15-20% |
| 104 | + higher memory use (geometric mean, as measured by pyperformance). We |
| 105 | + haven't spent a lot of time trying to lower this yet, so we may be able to |
| 106 | + push this down further. Realistically, though, higher memory use is the |
| 107 | + cost of having efficient, safe free-threading, and we are unlikely to get |
| 108 | + this very close to the with-GIL build's memory use without significant |
| 109 | + performance cost. |
| 110 | + |
| 111 | +- Stable ABI. Stable ABI support is mentioned by the Steering Council as a |
| 112 | + potential requirement for phase II. While having Stable ABI support would |
| 113 | + make third-party package distribution a lot easier, there's a bit of a |
| 114 | + chicken and egg problem: we don't know if the Stable ABI is good enough |
| 115 | + if we don't have packages that support free-threaded Python using it, and |
| 116 | + we can't remove things from the Stable ABI if we discover problems with |
| 117 | + them. Given that phase II is meant to give the community time to adopt |
| 118 | + free-threaded Python and provide feedback on APIs and ABIs, we're not |
| 119 | + sure how strong a requirement the Stable ABI should be for phase II. |
| 120 | + |
| 121 | +Specification |
| 122 | +============= |
| 123 | + |
| 124 | +Specific criteria for making free-threaded Python officially supported |
| 125 | +(phase II), as we propose them: |
| 126 | + |
| 127 | +- Acceptable performance. The Steering Council mentioned they expected |
| 128 | + free-threaded Python to be around 10-15% slower, although this was not a |
| 129 | + hard target. We are currently around 10% and don't expect it to get |
| 130 | + slower, but for phase II (not the default flip), we propose 15% as a hard performance target. |
| 131 | + |
| 132 | +- Acceptable memory use. This was not mentioned by the Steering Council and |
| 133 | + hasn't seen much discussion. We propose a target of 20% (geometric mean, |
| 134 | + as measured by pyperformance) for phase II. For phase III, we'll need |
| 135 | + input from the community as to where the trade-off between memory and CPU |
| 136 | + performance should end up. |
| 137 | + |
| 138 | +- Proven, stable APIs. This is a difficult thing to measure, but we have |
| 139 | + seen significant adoption of free-threaded Python with the existing APIs, |
| 140 | + and have not had to radically change any existing APIs to accommodate |
| 141 | + them. We will probably end up adding some more convenience APIs for |
| 142 | + specific use-cases in the future, but we believe we have proven the |
| 143 | + viability and stability of the APIs we have. We have not needed |
| 144 | + breaking changes in new APIs, and we expect all future changes |
| 145 | + to follow :pep:`387`'s change policy. |
| 146 | + |
| 147 | +- Internal documentation. We have multiple Core Developers working on |
| 148 | + free-threaded Python, including several who recently started working on |
| 149 | + fixing thread-safety issues in specific modules, but we probably need to |
| 150 | + shore up the introductory documentation for the internals of |
| 151 | + free-threaded Python. This should not be a problem to achieve for 3.14. |
| 152 | + |
| 153 | +With these criteria satisfied, we believe Python 3.14 is the right time frame |
| 154 | +for phase II of :pep:`703`. |
| 155 | + |
| 156 | +(Note that these are requirements for entering phase II *only*. The decision |
| 157 | +to make free-threaded Python the default (phase III) is very different, and |
| 158 | +we expect it will revolve around community support, willingness, and showing |
| 159 | +clear benefit. That's left for a future PEP.) |
| 160 | + |
| 161 | +Open Issues |
| 162 | +=========== |
| 163 | + |
| 164 | +- Should the Stable ABI be a strong requirement for "supported" status of the free-threaded build? |
| 165 | + |
| 166 | + |
| 167 | +Footnotes |
| 168 | +========= |
| 169 | + |
| 170 | +Copyright |
| 171 | +========= |
| 172 | + |
| 173 | +This document is placed in the public domain or under the |
| 174 | +CC0-1.0-Universal license, whichever is more permissive. |
0 commit comments