Skip to content

Commit 9d017fb

Browse files
authored
PEP 779: Criteria for supported status for free-threaded Python initial draft. (#4301)
Initial draft of PEP 703 phase II promotion requirements.
1 parent e9e1214 commit 9d017fb

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

peps/pep-0779.rst

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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

Comments
 (0)