-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
dtoa: thread safety in --disable-gil
builds
#111962
Comments
@mdickinson for awareness. |
Thanks, @ericvsmith.
I'm not opposed to moving away from dtoa.c (quite the opposite), but it's important to recognise just how much dtoa.c is doing for us right now - not just float-to-string in all its wonderful variants (shortest string, correctly-rounded fixed precision including the case of negative precision, correctly-rounded fixed number of significant digits) but correctly-rounded string-to-float, too. I like the look of dragonbox, but it only covers one subcase (shortest string) of one direction (float-to-string). We'd need to find substitutes for all the various pieces of dtoa.c. |
The suggested mitigations for (1) and (2) sound good to me, FWIW. |
I guess we should probably open a separate issue if we want to explore the idea of moving away from |
Scratch that; the README says "We encourage users to adopt fast_float library instead". |
@mdickinson, thanks for the context. I'll plan on only making minimal changes to dtoa to make it thread-safe. |
This avoids using the Bigint free-list in `--disable-gil` builds, and pre-computes the needed powers of 5 during interpreter initialization. This makes two changes to dtoa
This avoids using the Bigint free-list in `--disable-gil` builds and pre-computes the needed powers of 5 during interpreter initialization.
This avoids using the Bigint free-list in `--disable-gil` builds and pre-computes the needed powers of 5 during interpreter initialization.
This updates `dtoa.c` to avoid using the Bigint free-list in --disable-gil builds and to pre-computes the needed powers of 5 during interpreter initialization. * gh-111962: Make dtoa thread-safe in `--disable-gil` builds. This avoids using the Bigint free-list in `--disable-gil` builds and pre-computes the needed powers of 5 during interpreter initialization. * Fix size of cached powers of 5 array. We need the powers of 5 up to 5**512 because we only jump straight to underflow when the exponent is less than -512 (or larger than 308). * Rename Py_NOGIL to Py_GIL_DISABLED * Changes from review * Fix assertion placement
…thon#112049) This updates `dtoa.c` to avoid using the Bigint free-list in --disable-gil builds and to pre-computes the needed powers of 5 during interpreter initialization. * pythongh-111962: Make dtoa thread-safe in `--disable-gil` builds. This avoids using the Bigint free-list in `--disable-gil` builds and pre-computes the needed powers of 5 during interpreter initialization. * Fix size of cached powers of 5 array. We need the powers of 5 up to 5**512 because we only jump straight to underflow when the exponent is less than -512 (or larger than 308). * Rename Py_NOGIL to Py_GIL_DISABLED * Changes from review * Fix assertion placement
…thon#112049) This updates `dtoa.c` to avoid using the Bigint free-list in --disable-gil builds and to pre-computes the needed powers of 5 during interpreter initialization. * pythongh-111962: Make dtoa thread-safe in `--disable-gil` builds. This avoids using the Bigint free-list in `--disable-gil` builds and pre-computes the needed powers of 5 during interpreter initialization. * Fix size of cached powers of 5 array. We need the powers of 5 up to 5**512 because we only jump straight to underflow when the exponent is less than -512 (or larger than 308). * Rename Py_NOGIL to Py_GIL_DISABLED * Changes from review * Fix assertion placement
Feature or enhancement
The
Python/dtoa.c
library is responsible for formatting floating point numbers (double
) as strings and for parsing strings into numbers. The shared state is not thread-safe without the GIL:Balloc
andBfree
use a per-interpreter free-list to avoid some allocations ofBigint
objectspow5mult
uses a per-interpreter append-only list ofBigint
powers of 5For (1), we can just skip using the freelists in
--disable-gil
builds. We already have a code path (Py_USING_MEMORY_DEBUGGER
) that doesn't use freelists.cpython/Python/dtoa.c
Line 312 in d61313b
For (2), we can use atomic operations to append to the powers-of-5 linked list in a thread-safe manner. I don't think this needs to be guarded by a
Py_NOGIL
checks, since each power-of-5 is only ever created once.For context, here is the modification to
Python/dtoa.c
in nogil-3.12. Note that it uses aPyMutex
for (2), which I think we can avoid.dragonbox, Ryū, Grisu, Schubfach
In the past 5 or so years, there have been a number of faster float-to-string algorithms with the desirable attributes (correctly rounded, no "garabage" digits, etc.). To my knowledge they are also all thread-safe. "dragonbox" looks the most promising, but porting it to C is a bigger undertaking than making the existing
dtoa.c
thread-safe.Linked PRs
--disable-gil
builds. #112049The text was updated successfully, but these errors were encountered: