[Python-Dev] Version 2 of PEP 670 – Convert macros to functions in the Python C API
Hi, Since Erlend and me posted PEP 670 on python-dev last October, we took all feedback (python-dev and Steering Council) in account to clarify the intent of the PEP and to reduce its scope (remove *any* risk of backward compatibility). PEP 670: https://python.github.io/peps/pep-0670/ Changes since the first version: * Stricter policy on not changing argument types and return type. * Better explain why pointer arguments require a cast to not emit new compiler warnings. * Macros which can be used as l-values are no longer modified by the PEP (I wrote PEP 674 just for that). * Macros having multiple return types are no longer modified by the PEP. * Limited C API version 3.11 no longer casts pointer arguments (move towards a cleaner API, but only if you opt in for that!). * No longer remove return values of macros "which should not have a return value" (this rule was complicated and in fact, all macros have already been fixed). * Add "Macros converted to functions since Python 3.8" section to show that macros already converted didn't introduce performance issue nor new compiler warnings. * Add "Benchmark comparing macros and static inline functions" section to prove that there is no significant impact on performance. Note: we already submitted PEP 670 to the Steering Council at the end of November, and the SC 2022 came with feedback, so we modified the PEP: https://mail.python.org/archives/list/python-dev@python.org/message/IJ3IBVY3JDPROKX55YNDT6XZTVTTPGOP/ Following the SC decision, we already modified PEP 7 to add: "static inline functions should be preferred over macros in new code." https://www.python.org/dev/peps/pep-0007/#c-dialect Victor -- Night gathers, and now my watch begins. It shall not end until my death. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/VM6I3UHVMME6QRSUOYLK6N2OZHP454W6/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] SC Acceptance: PEP 680 -- tomllib
Hello, The Steering Council discussed PEP 680 -- tomllib: Support for Parsing TOML in the Standard Library, and unanimously decided to accept it. Congratulations! I'll change the PEP status to Accepted. Please open a PR for Python 3.11 at your convenience. - Petr (on behalf of the Python Steering Council) ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/3AHGWYY562HHO55L4Z2OVYUFZP5W73IS/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] SC reply to PEP 674 -- Disallow using macros as l-values
Hello, Thank you for submitting PEP 674 -- Disallow using macros as l-values! For Py_TYPE, we respect the previous steering council's decision: https://github.com/python/steering-council/issues/79 The Py_TYPE macro can be changed as proposed in 3.11. However, the old SC explicitly noted that the exception only applies to Py_SET_TYPE, and that in general, there should be a deprecation notice in some way or form. After deliberating the proposed changes, the SC agrees that they will make CPython better. However, we are not convinced that they should be made *right now*. We see no reason to rush. We would like to ask you to rework the PEP to reflect these suggestions. It is not feasible to provide visible deprecation warnings for the proposed changes. We feel that this is not a good reason to skip the deprecation process entirely. Quite the opposite: if we need to skip a step, we should move even more carefully than usual. We suggest the following process: First, add notices to any documentation that using the macro as a l-value is a deprecated, CPython-specific detail. It should be clear that the only reason this usage is allowed is for backwards compatibility, and that alternate implementations of the C API are free to not allow this. Then, wait until all supported versions of CPython include any relevant replacement macros such as Py_SET_SIZE. (This doesn't mean adding "set" variants to all the changed macros -- just to those few where setting can be useful and safe.) With the current schedule, this means waiting until Python 3.14, which is planned for October 2024, when Python 3.8 will reach end-of-life. The SC can give an exception to shorten the wait for specific macros, if there is a real benefit to it. (For example: the nogil branch should include any necessary changes, and they should be approved and merged with nogil itself). Finally, ask the new Steering Council to make the change and finally disallow using the macros as l-values. If there's no negative feedback or unexpected downsides, we hope that the future SC will summarily approve. Hopefully, this strategy will also work for PyDescr_NAME and other macros that were left out of the PEP for now. Additionally, consider making the change in the 3.11 version of the limited API. This version is opt-in, so users are free to do the switch when it is convenient for them. Also, it would allow early testing and review of the changes. Further discussion about this should happen on python-dev, like usual. - Petr, on behalf of the Steering Council ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/CV6KWDRHV5WP6TIDK3Z46PW7HNSHYOWG/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: SC reply to PEP 674 -- Disallow using macros as l-values
Hi, Thanks for looking into my PEP 674! I don't understand well why Py_SIZE() cannot be changed until Py_SET_SIZE() is available on all supported Python versions (so affected projects don't have to add a compatibility code), whereas it's ok to require a compatibility code to keep support for Python 3.8 and older for the approved Py_TYPE() change (Py_SET_TYPE was added to Python 3.9). Many projects affected by the Py_SIZE() change are already affected by the Py_TYPE() change, and so need a compatibility code anyway: 33% (5/15) of affected projects are affected by Py_SIZE() and Py_TYPE() changes (see below). Not changing Py_SIZE() now avoids adding a compatibility code to the 33% (5/15) of affected projects only affected by the Py_SIZE() change. Either changing Py_TYPE() *and* Py_SIZE(), or none, would make more sense to me. Well, I would prefer to change both, since the work is already done. The change is already part of Python 3.11 and all projects known to be afffected are already fixed. And the Py_TYPE() change was already approved. -- The Py_TYPE() change requires a compatibility code to get Py_SET_TYPE() on Python 3.8 and older, use pythoncapi_compat.h or add: #if PY_VERSION_HEX < 0x030900A4 # define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0) #endif The Py_SIZE() change requires a similar compatibility code. For example, boost defines Py_SET_TYPE() *and* Py_SET_SIZE(): #if PY_VERSION_HEX < 0x030900A4 # define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0) # define Py_SET_SIZE(obj, size) ((Py_SIZE(obj) = (size)), (void)0) #endif -- Affected projects from PEP 674. Projects affected by Py_SIZE() and Py_TYPE() changes (5): * guppy3: Py_SET_TYPE(), Py_SET_SIZE(), Py_SET_REFCNT(), use pythoncapi_compat.h * bitarray: Py_SET_TYPE(), Py_SET_SIZE(), use pythoncapi_compat.h * mypy: Py_SET_TYPE(), Py_SET_SIZE(), use pythoncapi_compat.h * numpy: Py_SET_TYPE(), Py_SET_SIZE(), custom compatibility code * boost: Py_SET_TYPE(), Py_SET_SIZE(), custom compatibility code Projects only affected by the Py_SIZE() change (5): * python-snappy: Py_SET_SIZE(), use pythoncapi_compat.h * recordclass: use custom py_refcnt() and py_set_size() macros * Cython: Py_SET_SIZE(), Py_SET_REFCNT(), custom compatibility code * immutables: Py_SET_SIZE(), use pythoncapi_compat.h * zstd: Py_SET_SIZE(), use pythoncapi_compat.h Projects only affected by Py_TYPE() change (5): * datatable: Py_SET_TYPE(), Py_SET_REFCNT(), use pythoncapi_compat.h * mercurial: Py_SET_TYPE(), use pythoncapi_compat.h * pycurl: Py_SET_TYPE(), custom compatibility code * duplicity: Py_SET_TYPE(), test PY_MAJOR_VERSION and PY_MINOR_VERSION, or use Py_TYPE() as l-value * gobject-introspection: Py_SET_TYPE(), custom compatibility code These examples don't count the larger number of affected projects using Cython which only need to re-run Cython to use Py_SET_REFCNT(), Py_SET_TYPE() and Py_SET_SIZE(). I would like to add that 100% of the top 5000 PyPI projects are already fixed for PEP 674, but 26 projects need a release including a fix (which will likely happend before Python 3.11 final release). Victor -- Night gathers, and now my watch begins. It shall not end until my death. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/YQOSKYGDGRKBAFYW2AJQIIMYMQHALUOQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: SC reply to PEP 674 -- Disallow using macros as l-values
On Tue, Feb 22, 2022 at 1:54 PM Petr Viktorin wrote: > First, add notices to any documentation that using the macro as a > l-value is a deprecated, CPython-specific detail. It should be clear > that the only reason this usage is allowed is for backwards > compatibility, and that alternate implementations of the C API are free > to not allow this. In practice, alternate implementations must implement exactly the same C API than CPython, otherwise they become incompatible with projects affected by PEP 674 (41 projects including major projects like Cython and numpy). Let me quote Matti about the PyPy project: "I think it would be more accurate to say that PyPy, as a small project in the huge Python ecosystem, is trying to support any C-API used widely by the community. If there is a common PyPy voice (after all, we are also a project with many opinions), we don't "not want to drop support" nor "want to drop support" for any commonly used C-API interfaces, rather we want to stay out of this argument and promote alternatives such as CFFI, cppyy, and HPy instead." https://mail.python.org/archives/list/python-dev@python.org/message/3HGX42QFURHCU6O6DOKBXLVTFIU6RDBO/ The whole purpose of PEP 674 is to remove this constraint in alternate implementations *and* in CPython. Victor -- Night gathers, and now my watch begins. It shall not end until my death. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/NQG7HXB3LG6S4CPGBYCH3IZSTRSECUYE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] PyCon 2022: Call For Papers!
Hi, I am working with the PyCon Estonia team, helping them organise a conference this year. The last three PyCon events were a great success and after a year of break due to corona, we want to come back to keep on bringing the Python community together in Tallinn. As we are preparing for PyCon Estonia 2020, we have also announced our call for papers. We are looking for talks on various topics. The theme this year is "Connect. Collab. Contribute" and we want the focus of the conference to be around the Python ecosystem. However, we are also welcoming talks on other relevant topics - Python challenges, outstanding packages, security, automation, AI/ML, web development, IoT, mental health for developers, conducive work environment for coding, etc. I would like to invite you to participate in the call for papers and be a part of PyCon Estonia 2022 as a speaker. We are waiting for the proposals before the 1st of April here: https://pyconestonia.typeform.com/to/HSWhN8YW We would have a team from our end review the proposals anonymously and reach out to you if the talk fits with the overall theme. As a speaker, you do not need to purchase the tickets for the event and if you already have, we'll be happy to make a refund or transfer. If you have any questions please do not hesitate to reach out to me. Looking forward to having you with us at PyCon on 25th of August, 2022. Best Wishes, -- Grete Kungla +372 5628 0032 Project Manager PyCon Conference 2022 https://pycon.ee/ ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/OVEPTJ45MCP6DWFXIUZC32KCL4I7F6TV/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount"
Hey Inada, thanks for the feedback > Generally speaking, fork is a legacy API. It is too difficult to know which > library is fork-safe, even for stdlibs. Yes, this is something that Instagram has to go into great lengths to make sure that we get the entire execution into a state where it's safe to fork. It works, but it's hard to maintain. We'd rather have a simpler model! > I hope per-interpreter GIL replaces fork use cases. We hope so too, hence the big push towards having immutable shared state across the interpreters. For large applications like Instagram, this is a must, otherwise copying state into every interpreter would be too costly. > Anyway, I don't believe stopping refcounting will fix the CoW issue yet. See > this article [1] again. That article is five years old so it doesn't reflect the current state of the system! We have continuous profiling and monitoring of Copy on Writes and after introducing the techniques described in this PEP, we have largely fixed the majority of scenarios where this happens. You are right in the fact that just addressing reference counting will not fix all CoW issues. The trick here is also to leverage the permanent GC generation used for the `gc.freeze` API. That is, if you have a container that it's known to be immortal, it should be pushed into the permanent GC generation. This will guarantee that the GC itself will not change the GC headers of said instance. Thus, if you immortalize your heap before forking (using the techniques in: https://github.com/python/cpython/pull/31489) then you'll end up removing the vast majority of scenarios where CoW takes place. I can look into writing a new technical article for Instagram with more up to date info but this might take time to get through! Now, I said that we've largely fixed the CoW issue because there are still places where it happens such as: free lists, the small object allocator, etc. But these are relatively small compared to the ones coming from reference counts and the GC head mutations. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/TBXKYD6OOR7I5QAMTE3VAJT5YCDISOET/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
Thanks for the feedback. I've responded inline below. -eric On Sat, Feb 19, 2022 at 8:50 PM Inada Naoki wrote: > I hope per-interpreter GIL success at some point, and I know this is > needed for per-interpreter GIL. > > But I am worrying about per-interpreter GIL may be too complex to > implement and maintain for core developers and extension writers. > As you know, immortal don't mean sharable between interpreters. It is > too difficult to know which object can be shared, and where the > shareable objects are leaked to other interpreters. > So I am not sure that per interpreter GIL is achievable goal. I plan on addressing this in the PEP I am working on for per-interpreter GIL. In the meantime, I doubt the issue will impact any core devs. > So I think it's too early to introduce the immortal objects in Python > 3.11, unless it *improve* performance without per-interpreter GIL > Instead, we can add a configuration option such as > `--enalbe-experimental-immortal`. I agree that immortal objects aren't quite as appealing in general without per-interpreter GIL. However, there are actual users that will benefit from it, assuming we can reduce the performance penalty to acceptable levels. For a recent example, see https://mail.python.org/archives/list/python-dev@python.org/message/B77BQQFDSTPY4KA4HMHYXJEV3MOU7W3X/. > On Sat, Feb 19, 2022 at 4:52 PM Eric Snow wrote: > > > > Reducing CPU Cache Invalidation > > --- > > > > Avoiding Data Races > > --- > > > > Both benefits require a per-interpreter GIL. CPU cache invalidation exists regardless. With the current GIL the effect it is reduced significantly. Per-interpreter GIL is only one situation where data races matter. Any attempt to generally eliminate the GIL must deal with races on the per-object runtime state. > > > > Avoiding Copy-on-Write > > -- > > > > For some applications it makes sense to get the application into > > a desired initial state and then fork the process for each worker. > > This can result in a large performance improvement, especially > > memory usage. Several enterprise Python users (e.g. Instagram, > > YouTube) have taken advantage of this. However, the above > > refcount semantics drastically reduce the benefits and > > has led to some sub-optimal workarounds. > > > > As I wrote before, fork is very difficult to use safely. We can not > recommend to use it for many users. > And I don't think reducing the size of patch in Instagram or YouTube > is not good rational for this kind of change. What do you mean by "this kind of change"? The proposed change is relatively small. It certainly isn't nearly as intrusive as many changes we make to internals without a PEP. If you are talking about the performance penalty, we should be able to eliminate it. > > Also note that "fork" isn't the only operating system mechanism > > that uses copy-on-write semantics. Anything that uses ``mmap`` > > relies on copy-on-write, including sharing data from shared objects > > files between processes. > > > > It is very difficult to reduce CoW with mmap(MAP_PRIVATE). > > You may need to write hash of bytes and unicode. You may be need to > write `tp_type`. > Immortal objects can "reduce" the memory write. But "at least one > memory write" is enough to trigger the CoW. Correct. However, without immortal objects (AKA immutable per-object runtime-state) it goes from "very difficult" to "basically impossible". > > Accidental Immortality > > -- > > > > While it isn't impossible, this accidental scenario is so unlikely > > that we need not worry. Even if done deliberately by using > > ``Py_INCREF()`` in a tight loop and each iteration only took 1 CPU > > cycle, it would take 2^61 cycles (on a 64-bit processor). At a fast > > 5 GHz that would still take nearly 500,000,000 seconds (over 5,000 days)! > > If that CPU were 32-bit then it is (technically) more possible though > > still highly unlikely. > > > > Technically, `[obj] * (2**(32-4))` is 1GB array on 32bit. The question is if this matters. If really necessary, the PEP can demonstrate that it doesn't matter in practice. (Also, the magic value on 32-bit would be 2**29.) > > > > Constraints > > --- > > > > * ensure that otherwise immutable objects can be truly immutable > > * be careful when immortalizing objects that are not otherwise immutable > > I am not sure about what this means. > For example, unicode objects are not immutable because they have hash, > utf8 cache and wchar_t cache. (wchar_t cache will be removed in Python > 3.12). I think you understood it correctly. In the case of str objects, they are close enough since a race on any of those values will not cause a different outcome. I will clarify the point in the PEP. > > Object Cleanup > > -- > > > > In order to clean up all immortal objects during runtime finalization, > > we must keep track of them. > > > > I don't
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
Thanks for the responses. I've replied inline below. -eric On Mon, Feb 21, 2022 at 9:11 AM Petr Viktorin wrote: > > On 19. 02. 22 8:46, Eric Snow wrote: > > Thanks to all those that provided feedback. I've worked to > > substantially update the PEP in response. The text is included below. > > Further feedback is appreciated. > > Thank you! This version is much clearer. I like the PEP more and more! Great! > I've sent a PR with a some typo fixes: > https://github.com/python/peps/pull/2348 Thank you. > > Public Refcount Details > [...] > > As part of this proposal, we must make sure that users can clearly > > understand on which parts of the refcount behavior they can rely and > > which are considered implementation details. Specifically, they should > > use the existing public refcount-related API and the only refcount value > > with any meaning is 0. All other values are considered "not 0". > > Should we care about hacks/optimizations that rely on having the only > reference (or all references), e.g. mutating a tuple if it has refcount > 1? Immortal objects shouldn't break them (the special case simply won't > apply), but this wording would make them illegal. > AFAIK CPython uses this internally, but I don't know how > prevalent/useful it is in third-party code. Good point. As Terry suggested, we could also let 1 have meaning. Regardless, any documented restriction would only apply to users of the public C-API, not to internal code. > > _Py_IMMORTAL_REFCNT > > --- > > > > We will add two internal constants:: > > > > #define _Py_IMMORTAL_BIT (1LL << (8 * sizeof(Py_ssize_t) - 4)) > > #define _Py_IMMORTAL_REFCNT (_Py_IMMORTAL_BIT + (_Py_IMMORTAL_BIT / 2)) > > As a nitpick: could you say this in prose? > > * ``_Py_IMMORTAL_BIT`` has the third top-most bit set. > * ``_Py_IMMORTAL_REFCNT`` has the third and fourth top-most bits set. Sure. > > Immortal Global Objects > > --- > > > > All objects that we expect to be shared globally (between interpreters) > > will be made immortal. That includes the following: > > > > * singletons (``None``, ``True``, ``False``, ``Ellipsis``, > > ``NotImplemented``) > > * all static types (e.g. ``PyLong_Type``, ``PyExc_Exception``) > > * all static objects in ``_PyRuntimeState.global_objects`` (e.g. > > identifiers, > >small ints) > > > > All such objects will be immutable. In the case of the static types, > > they will be effectively immutable. ``PyTypeObject`` has some mutable > > start (``tp_dict`` and ``tp_subclasses``), but we can work around this > > by storing that state on ``PyInterpreterState`` instead of on the > > respective static type object. Then the ``__dict__``, etc. getter > > will do a lookup on the current interpreter, if appropriate, instead > > of using ``tp_dict``. > > But tp_dict is also public C-API. How will that be handled? > Perhaps naively, I thought static types' dicts could be treated as > (deeply) immutable, and shared? They are immutable from Python code but not from C (due to tp_dict). Basically, we will document that tp_dict should not be used directly (in the public API) and refer users to a public getter function. I'll note this in the PEP. > Perhaps it would be best to leave it out here and say say "The details > of sharing ``PyTypeObject`` across interpreters are left to another PEP"? > Even so, I'd love to know the plan. What else would you like to know? There isn't much to it. For each of the builtin static types we will keep the relevant mutable state on PyInterpreterState and look it up there in the relevant getters (e.g. __dict__ and __subclasses__). > (And even if these are internals, > changes to them should be mentioned in What's New, for the sake of > people who need to maintain old extensions.) +1 > > Object Cleanup > > -- > > > > In order to clean up all immortal objects during runtime finalization, > > we must keep track of them. > > > > For GC objects ("containers") we'll leverage the GC's permanent > > generation by pushing all immortalized containers there. During > > runtime shutdown, the strategy will be to first let the runtime try > > to do its best effort of deallocating these instances normally. Most > > of the module deallocation will now be handled by > > ``pylifecycle.c:finalize_modules()`` which cleans up the remaining > > modules as best as we can. It will change which modules are available > > during __del__ but that's already defined as undefined behavior by the > > docs. Optionally, we could do some topological disorder to guarantee > > that user modules will be deallocated first before the stdlib modules. > > Finally, anything leftover (if any) can be found through the permanent > > generation gc list which we can clear after finalize_modules(). > > > > For non-container objects, the tracking approach will vary on a > > case-by-case basis. In nearly every case, each such object is directly > > accessible on the runti
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
On Mon, Feb 21, 2022 at 10:56 AM wrote: > For what it's worth Cython does this for string concatenation to concatenate > in place if possible (this optimization was copied from CPython). It could be > disabled relatively easily if it became a problem (it's already CPython only > and version checked so it'd just need another upper-bound version check). That's good to know. -eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/OEZS4KGQJET5DL3M2OTB76I4W7F56FJC/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
On Mon, Feb 21, 2022 at 4:56 PM Terry Reedy wrote: > We could say that the only refcounts with any meaning are 0, 1, and > 1. Yeah, that should work. -eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7HZ7VBJQOYHXFV3ZD4V7DCMLBL4Q34WP/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
On Sat, Feb 19, 2022 at 12:46 AM Eric Snow wrote: > Performance > --- > > A naive implementation shows `a 4% slowdown`_. > Several promising mitigation strategies will be pursued in the effort > to bring it closer to performance-neutral. See the `mitigation`_ > section below. FYI, Eddie has been able to get us back to performance-neutral after applying several of the mitigation strategies we discussed. :) -eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/ZYGZEQSVBS6ODVAHPL3QN4CJ7JN4FYWO/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
On Wed, Feb 23, 2022 at 10:12 AM Eric Snow wrote: > > Thanks for the feedback. I've responded inline below. > > -eric > > On Sat, Feb 19, 2022 at 8:50 PM Inada Naoki wrote: > > I hope per-interpreter GIL success at some point, and I know this is > > needed for per-interpreter GIL. > > > > But I am worrying about per-interpreter GIL may be too complex to > > implement and maintain for core developers and extension writers. > > As you know, immortal don't mean sharable between interpreters. It is > > too difficult to know which object can be shared, and where the > > shareable objects are leaked to other interpreters. > > So I am not sure that per interpreter GIL is achievable goal. > > I plan on addressing this in the PEP I am working on for > per-interpreter GIL. In the meantime, I doubt the issue will impact > any core devs. > It's nice to hear! > > So I think it's too early to introduce the immortal objects in Python > > 3.11, unless it *improve* performance without per-interpreter GIL > > Instead, we can add a configuration option such as > > `--enalbe-experimental-immortal`. > > I agree that immortal objects aren't quite as appealing in general > without per-interpreter GIL. However, there are actual users that > will benefit from it, assuming we can reduce the performance penalty > to acceptable levels. For a recent example, see > https://mail.python.org/archives/list/python-dev@python.org/message/B77BQQFDSTPY4KA4HMHYXJEV3MOU7W3X/. > It is not proven example, but just a hope at the moment. So option is fine to prove the idea. Although I can not read the code, they said "patching ASLR by patching `ob_type` fields;". It will cause CoW for most objects, isn't it? So reducing memory write don't directly means reducing CoW. Unless we can stop writing on a page completely, the page will be copied. > > On Sat, Feb 19, 2022 at 4:52 PM Eric Snow > > wrote: > > > > > > Reducing CPU Cache Invalidation > > > --- > > > > > > Avoiding Data Races > > > --- > > > > > > > Both benefits require a per-interpreter GIL. > > CPU cache invalidation exists regardless. With the current GIL the > effect it is reduced significantly. > It's an interesting point. We can not see the benefit from pypeformance, because it doesn't use much data and it runs one process at a time. So the pyperformance can not make enough stress to the last level cache which is shared by many cores. We need multiprocess performance benchmark apart from pyperformance, to stress the last level cache from multiple cores. It helps not only this PEP, but also optimizing containers like dict and set. > > > > As I wrote before, fork is very difficult to use safely. We can not > > recommend to use it for many users. > > And I don't think reducing the size of patch in Instagram or YouTube > > is not good rational for this kind of change. > > What do you mean by "this kind of change"? The proposed change is > relatively small. It certainly isn't nearly as intrusive as many > changes we make to internals without a PEP. If you are talking about > the performance penalty, we should be able to eliminate it. > Can proposed optimizations to eliminate the penalty guarantee that every __del__, weakref are not broken, and no memory leak occurs when the Python interpreter is initialized and finalized multiple times? I haven't confirmed it yet. > > > Also note that "fork" isn't the only operating system mechanism > > > that uses copy-on-write semantics. Anything that uses ``mmap`` > > > relies on copy-on-write, including sharing data from shared objects > > > files between processes. > > > > > > > It is very difficult to reduce CoW with mmap(MAP_PRIVATE). > > > > You may need to write hash of bytes and unicode. You may be need to > > write `tp_type`. > > Immortal objects can "reduce" the memory write. But "at least one > > memory write" is enough to trigger the CoW. > > Correct. However, without immortal objects (AKA immutable per-object > runtime-state) it goes from "very difficult" to "basically > impossible". > Configuration option won't make it impossible. > > > > > > Constraints > > > --- > > > > > > * ensure that otherwise immutable objects can be truly immutable > > > * be careful when immortalizing objects that are not otherwise immutable > > > > I am not sure about what this means. > > For example, unicode objects are not immutable because they have hash, > > utf8 cache and wchar_t cache. (wchar_t cache will be removed in Python > > 3.12). > > I think you understood it correctly. In the case of str objects, they > are close enough since a race on any of those values will not cause a > different outcome. > > I will clarify the point in the PEP. > FWIW, I filed an issue to remove hash cache from bytes objects. https://github.com/faster-cpython/ideas/issues/290 Code objects have many bytes objects, (e.g. co_code, co_linetable, etc...) Removing it will save some RAM usage and make im
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount"
On Wed, Feb 23, 2022 at 1:46 AM Eddie Elizondo via Python-Dev wrote: > > > That article is five years old so it doesn't reflect the current state of the > system! We have continuous profiling and monitoring of Copy on Writes and > after introducing the techniques described in this PEP, we have largely fixed > the majority of scenarios where this happens. > > You are right in the fact that just addressing reference counting will not > fix all CoW issues. The trick here is also to leverage the permanent GC > generation used for the `gc.freeze` API. That is, if you have a container > that it's known to be immortal, it should be pushed into the permanent GC > generation. This will guarantee that the GC itself will not change the GC > headers of said instance. > > Thus, if you immortalize your heap before forking (using the techniques in: > https://github.com/python/cpython/pull/31489) then you'll end up removing the > vast majority of scenarios where CoW takes place. I can look into writing a > new technical article for Instagram with more up to date info but this might > take time to get through! > > Now, I said that we've largely fixed the CoW issue because there are still > places where it happens such as: free lists, the small object allocator, etc. > But these are relatively small compared to the ones coming from reference > counts and the GC head mutations. Same technique don't guarantee same benefit. Like gc.freeze() is needed before immortalize to avoid CoW, some other tricks may be needed too. New article is welcome, but I want sample application we can run, profile, and measure the benefits. Regards, -- Inada Naoki ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/AUF5R62E7YT22LL4DJ5HI3FCS3ZPHSTL/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
On 2/22/22 6:00 PM, Eric Snow wrote: On Sat, Feb 19, 2022 at 12:46 AM Eric Snow wrote: Performance --- A naive implementation shows `a 4% slowdown`_. Several promising mitigation strategies will be pursued in the effort to bring it closer to performance-neutral. See the `mitigation`_ section below. FYI, Eddie has been able to get us back to performance-neutral after applying several of the mitigation strategies we discussed. :) Are these optimizations specifically for the PR, or are these optimizations we could apply without taking the immortal objects? Kind of like how Sam tried to offset the nogil slowdown by adding optimizations that we went ahead and added anyway ;-) //arry/ ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7GX4C3DQ23B2K5JXTOYQQPT2ZLJD7CP4/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" (round 2)
On Tue, Feb 22, 2022, 20:26 Larry Hastings wrote: > Are these optimizations specifically for the PR, or are these > optimizations we could apply without taking the immortal objects? Kind of > like how Sam tried to offset the nogil slowdown by adding optimizations > that we went ahead and added anyway ;-) > Basically all the optimizations require immortal objects. -eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/7VJVBFBWE3HWTPRVZH3WLSR7EZHZD337/ Code of Conduct: http://python.org/psf/codeofconduct/