[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Christian Heimes

On 14/12/2021 19.19, Eric Snow wrote:

A while back I concluded that neither approach would work for us.  The
approach I had taken would have significant cache performance
penalties in a per-interpreter GIL world.  The approach that modifies
Py_INCREF() has a significant performance penalty due to the extra
branch on such a frequent operation.


Would it be possible to write the Py_INCREF() and Py_DECREF() macros in 
a way that does not depend on branching? For example we could use the 
highest bit of the ref count as an immutable indicator and do something like


ob_refcnt += !(ob_refcnt >> 63)

instead of

ob_refcnt++

The code performs "ob_refcnt += 1" when the highest bit is not set and 
"ob_refcnt += 1" when the bit is set. I have neither tested if the 
approach actually works nor it's performance.


Christian
___
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/TBTHSOI2XRWRO6WQOLUW3X7S5DUXFAOV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Pablo Galindo Salgado
One thing to consider: ideally, inmortal objects should not participate in
the GC. There is nothing inheritly wrong if they do but we would need to
update the GC (and therefore add more branching in possible hot paths) to
deal with these as the algorithm requires the refcount to be exact to
correctly compute the cycles.

On Wed, 15 Dec 2021, 09:43 Christian Heimes,  wrote:

> On 14/12/2021 19.19, Eric Snow wrote:
> > A while back I concluded that neither approach would work for us.  The
> > approach I had taken would have significant cache performance
> > penalties in a per-interpreter GIL world.  The approach that modifies
> > Py_INCREF() has a significant performance penalty due to the extra
> > branch on such a frequent operation.
>
> Would it be possible to write the Py_INCREF() and Py_DECREF() macros in
> a way that does not depend on branching? For example we could use the
> highest bit of the ref count as an immutable indicator and do something
> like
>
>  ob_refcnt += !(ob_refcnt >> 63)
>
> instead of
>
>  ob_refcnt++
>
> The code performs "ob_refcnt += 1" when the highest bit is not set and
> "ob_refcnt += 1" when the bit is set. I have neither tested if the
> approach actually works nor it's performance.
>
> Christian
> ___
> 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/TBTHSOI2XRWRO6WQOLUW3X7S5DUXFAOV/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/GPZXLMYFNGEFPXHOG6W2MTAKU6MTEA7V/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Antoine Pitrou
On Wed, 15 Dec 2021 10:42:17 +0100
Christian Heimes  wrote:
> On 14/12/2021 19.19, Eric Snow wrote:
> > A while back I concluded that neither approach would work for us.  The
> > approach I had taken would have significant cache performance
> > penalties in a per-interpreter GIL world.  The approach that modifies
> > Py_INCREF() has a significant performance penalty due to the extra
> > branch on such a frequent operation.  
> 
> Would it be possible to write the Py_INCREF() and Py_DECREF() macros in 
> a way that does not depend on branching? For example we could use the 
> highest bit of the ref count as an immutable indicator and do something like
> 
>  ob_refcnt += !(ob_refcnt >> 63)
> 
> instead of
> 
>  ob_refcnt++

Probably, but that would also issue spurious writes to immortal
refcounts from different threads at once, so might end up worse
performance-wise.

Regards

Antoine.


___
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/ILW5G6BS6754S4G7A7OUNFBNOAB7DNN2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Nathaniel Smith
On Wed, Dec 15, 2021 at 2:21 AM Antoine Pitrou  wrote:
>
> On Wed, 15 Dec 2021 10:42:17 +0100
> Christian Heimes  wrote:
> > On 14/12/2021 19.19, Eric Snow wrote:
> > > A while back I concluded that neither approach would work for us.  The
> > > approach I had taken would have significant cache performance
> > > penalties in a per-interpreter GIL world.  The approach that modifies
> > > Py_INCREF() has a significant performance penalty due to the extra
> > > branch on such a frequent operation.
> >
> > Would it be possible to write the Py_INCREF() and Py_DECREF() macros in
> > a way that does not depend on branching? For example we could use the
> > highest bit of the ref count as an immutable indicator and do something like
> >
> >  ob_refcnt += !(ob_refcnt >> 63)
> >
> > instead of
> >
> >  ob_refcnt++
>
> Probably, but that would also issue spurious writes to immortal
> refcounts from different threads at once, so might end up worse
> performance-wise.

Unless the CPU is clever enough to skip claiming the cacheline in
exclusive-mode for a "+= 0". Which I guess is something you'd have to
check empirically on every microarch and instruction pattern you care
about, because there's no way it's documented. But maybe? CPUs are
very smart, except when they aren't.

-n

-- 
Nathaniel J. Smith -- https://vorpus.org
___
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/ZLARVPQCPZXWVHGYOZNSDRTCNNJ67ANM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: subinterpreters and their possible impact on large extension projects

2021-12-15 Thread Victor Stinner
Hi Brett,

IMO the PEP 630 is a good summary and a practical guide explaining how
to port existing C extensions to newer C API which are compatible with
subinterpreters, unloading a C extension and be able to load a C
extension more than once (in the same interpreter):
https://www.python.org/dev/peps/pep-0630/

I dislike justifying these changes only with subinterpreters. IMO it's
better to justify that these changes are needed to be able to load and
unload Python cleanly when an application embeds Python. A common use
case is to support plugins in different programming languages,
including Python. Some IRC clients and text editors have this use
case. It's unpleasant when Python leaks lot of memory when Python is
"unloaded", especially if the application is designed to load Python
once per plugin. It's even more unpleasant when... they are bugs :-(

Examples of changes needed by the PEP 630:

* Add a state to the module: use a PyModuleDef.m_size value greater
than 0 (usually a structure is used with ".m_size =
sizeof(_abcmodule_state)")
* Convert static types to heap types and store these types in the module state
* Move global variable and function "static" variables into the module state
* IMO the most complicated part is to retrieve the module state from
functions which don't directly get the module as an argument, but only
an instance of a type defined in the module. In some type "slot"
function, you will need to use ... a *private* function... which was
only added recently, in *Python 3.10*: _PyType_GetModuleByDef().

IMO the big problem of _PyType_GetModuleByDef() is that developers
want supporting Python versions older than Python 3.10. For example,
right now, numpy supports Python 3.7 and newer. Moreover, the fact
that the function remains private in Python 3.11 is also an issue.

Another challenge is how to check if a C extension is "fully"
compatible with subinterpreters?

In Python 3.11, Python still implements around 100 types as "static
types" which are not compatible with subinterpreters, like
&PyLong_Type and &PyUnicode_Type. I opened
https://bugs.python.org/issue40601 about these static types, but it
seems like changing it may break the C API *and* the stable ABI (maybe
a clever hack will avoid that).

One idea would be to add a macro excluding functions known to be
unsafe with subinterpreters from the C API. For example, exclude
"PyLong_Type" if the  Py_SUBINTERPRETER_API macro is defined. These
static types are accessed directly, but also indirectly. For example,
PyLong_CheckExact() is implemented as a macro which access directly
this type. Should we remove this function from the C API? Or implement
it as a regular "opaque" function if Py_SUBINTERPRETER_API is defined?

I would prefer an error at the build, rather than a crash at runtime :-(

Victor


On Wed, Dec 15, 2021 at 12:06 AM Brett Cannon  wrote:
>
>
>
> On Tue, Dec 14, 2021 at 9:41 AM Eric Snow  wrote:
>>
>> One of the open questions relative to subinterpreters is: how to
>> reduce the amount of work required for extension modules to support
>> them?  Thanks to Petr Viktorin for a lot of work he's done in this
>> area (e.g. PEP 489)!  Extensions also have the option to opt out of
>> subinterpreter support.
>>
>> However, that's only one part of the story.  A while back Nathaniel
>> expressed concerns with how making subinterpreters more accessible
>> will have a negative side effect affecting projects that publish large
>> extensions, e.g. numpy.  Not all extensions support subinterpreters
>> due to global state (incl. in library dependencies).  The amount of
>> work to get there may be large.  As subinterpreters increase in usage
>> in the community, so will demand increase for subinterpreter support
>> in those extensions.  Consequently, such projects be pressured to do
>> the extra work (which is made even more stressful by the short-handed
>> nature of most open source projects) .
>>
>> So we (the core devs) would effectively be requiring those extensions
>> to support subinterpreters, regardless of letting them opt out.  This
>> situation has been weighing heavily on my mind since Nathaniel brought
>> this up.  Here are some ideas I've had or heard of about what we could
>> do to help:
>>
>> * add a page to the C-API documentation about how to support subinterpreters
>> * identify the extensions most likely to be impacted and offer to help
>> * add more helpers to the C-API to make adding subinterpreter support
>> less painful
>> * fall back to loading the extension in its own namespace (e.g. use 
>> ldm_open())
>> * fall back to copying the extension's file and loading from the copied file
>> * ...
>>
>>  I'd appreciate your thoughts on what we can do to help.  Thanks!
>
>
> What are the requirements put upon an extension in order to support 
> subinterpreters? you hint at global state at the C level, but nothing else is 
> mentioned. Is that it?
> ___
> Python-Dev mailing list --

[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Victor Stinner
On Tue, Dec 14, 2021 at 7:27 PM Eric Snow  wrote:
> We have some options:
>
> * live with the full penalty
> * make other changes to reduce the penalty to a more acceptable
> threshold than 5%
> * eliminate the penalty (e.g. claw back 5% elsewhere)

The last time I saw a benchmark on immortal object, it was clearly 10%
slower overall on the pyperformance benchmark suite. That's a major
slowdown.

> * abandon all hope

I wrote https://bugs.python.org/issue39511 and
https://github.com/python/cpython/pull/18301 to have per-interpreter
None, True and False singletons. My change is backward compatible on
the C API: you can still use "Py_None" in your C code. The code gets
the singleton object from the current interpreter with a function
call:

#define Py_None Py_GetNone()

Py_GetNone() is implemented as: "return _PyInterpreterState_GET()->none;"

If _PyInterpreterState_GET() is modified to read a thread-local state,
similar to the on-going work to get the Python thread state from a
thread-local variable, Py_GetNone() should be "cheap" but I didn't run
a benchmark.

While I was working on this issue, I was fighting against other
challenges caused by subinterpreters. I fixed some of them since that
time.

By the way, I made the _Py_IDENTIFIER() API and _PyUnicode_FromId()
compatible with subinterpreters in Python 3.10. This change caused a
subtle regression when using subintepreters (because an optimization
made on an assumption on interned strings which is no longer true).
The fix is trivial but I didn't wrote it yet:
https://bugs.python.org/issue46006

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/GNPTATVA65JQEQUU2TZ7DAZZBAF5LMK7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Victor Stinner
Hi,

On Tue, Dec 14, 2021 at 6:13 PM Eric Snow  wrote:
> I'm still hoping to land a per-interpreter GIL for 3.11.  There is
> still a decent amount of work to be done but little of it will require
> solving any big problems:
>
> * pull remaining static globals into _PyRuntimeState and PyInterpreterState

I'm tracking remaining issues to get per-interpreter GIL at two places:

* https://bugs.python.org/issue40512
* https://pythondev.readthedocs.io/subinterpreters.html

I also wrote a recent summary of what has been done and what remains to be done:
https://vstinner.github.io/isolate-subinterpreters.html

Extract:

"""
There are still multiple interesting technical challenges:

* bpo-39511: Per-interpreter singletons (None, True, False, etc.)
* bpo-40601: Hide static types from the C API
* Make pymalloc allocator compatible with subinterpreters.
* Make the GIL per interpreter. Maybe even give the choice to share or
not the GIL when a subinterpreter is created.
* Make the _PyArg_Parser (parser_init()) function compatible with
subinterpreters. Maybe use a per-interpreter array, similar solution
than _PyUnicode_FromId().
* bpo-15751: Make the PyGILState API compatible with subinterpreters
(issue created in 2012!)
* bpo-40522: Get the current Python interpreter state from Thread
Local Storage (autoTSSkey)

Also, there are still many static types to convert to heap types
(bpo-40077) and many extension modules to convert to the multiphase
initialization API (bpo-163574).
"""

IMO "bpo-40601: Hide static types from the C API and "bpo-40522: Get
the current Python interpreter state from Thread Local Storage" are
non-trivial issues. Otherwise, they would already be solved. And these
are strict pre-requires to consider have one GIL per interpreter.


> * the objective has gotten a lot of support (and we're working on
> addressing the concerns of the few objectors)
> * most of the required work is worth doing regardless (e.g. improve
> runtime init/fini, eliminate static globals)
> * the performance impact is likely to be a net improvement
> * it is fully backward compatible and the C-API is essentially unaffected

The work required by subinterpreters help to cleaning up *all* Python
objects at exit which helps another use case: embed Python in an
application, especially load multiple instances of Python, when Python
is used as a plugin.

About the C API changes: until the "per GIL interpreter" feature is
fully implemented, I'm not 100% sure that no C API change is needed.
Obviously, I hope that no change will be needed ;-)

Also some changes needed by interpreters introduces a small slowdown.
I tried to measure it each time I noticed a potential slowdown. The
largest slowdown was the _PyUnicode_FromId() change was added 1
nanosecond per function call if I recall correctly.

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/6KERNBHC3LIEFF3GLXKPSC3NMQ37ISAF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Itamar O
+1 for consolidated documentation about per-interpreter GIL.

On Tue, Dec 14, 2021 at 9:12 AM Eric Snow 
wrote:

> Hi all,
>
> I'm still hoping to land a per-interpreter GIL for 3.11.  There is
> still a decent amount of work to be done but little of it will require
> solving any big problems:
>
> * pull remaining static globals into _PyRuntimeState and PyInterpreterState
> * minor updates to PEP 554
> * finish up the last couple pieces of the PEP 554 implementation
> * maybe publish a companion PEP about per-interpreter GIL
>
> There are also a few decisions to be made.  I'll open a couple of
> other threads to get feedback on those.  Here I'd like your thoughts
> on the following:
>
> Do we need a PEP about per-interpreter GIL?
>
> I haven't thought there would be much value in such a PEP.  There
> doesn't seem to be any decision that needs to be made.  At best the
> PEP would be an explanation of the project, where:
>

Even if there's no decision to be made, I think an informational PEP
would be valuable. Maybe even a Standards Track PEP? (since it
is technically a new feature)


>
> * the objective has gotten a lot of support (and we're working on
> addressing the concerns of the few objectors)
>
There's value in documenting the concerns and how they are being
addressed, and a PEP sounds like a good place to capture that.


> * most of the required work is worth doing regardless (e.g. improve
> runtime init/fini, eliminate static globals)
> * the performance impact is likely to be a net improvement
>
Also worth documenting that in the PEP (once there are benchmarks results).


> * it is fully backward compatible and the C-API is essentially unaffected
>
Since this is a likely concern, a PEP is a good place to address it.


>
> So the value of a PEP would be in consolidating an explanation of the
> project into a single document.  It seems like a poor fit for a PEP.
>

There is value in consolidating the project rationale, details, objections,
etc.
Is it a poor fit for a PEP? I don't know - is there a better alternative?
I guess it could be covered in the docs or devguide instead,
but I don't see a philosophical issue with using a PEP for this.


>
> (You might wonder, "what about PEP 554?"  I purposefully avoided any
> discussion of the GIL in PEP 554.  It's purpose is to expose
> subinterpreters to Python code.)
>
> However, perhaps I'm too close to it all.  I'd like your thoughts on the
> matter.


> Thanks!
>
> -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/PNLBJBNIQDMG2YYGPBCTGOKOAVXRBJWY/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/RK7B5NTBDRPEVKSTAF5TCL4N33RADZ5F/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Python release announcement format

2021-12-15 Thread Yann Droneaud

Hi,

Le 15/12/2021 à 02:42, Gregory P. Smith a écrit :
On Tue, Dec 14, 2021 at 9:06 AM Yann Droneaud  
wrote:


Should I open a bug for this issue ?


Makes sense, it is a pretty small change to make to the announcement 
format. Filed. https://bugs.python.org/issue46077


Thanks, you transcribed my thought perfectly !

--

Yann Droneaud

OPTEYA


___
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/GIEXAE73MY3A5X2XT5IYVFRFZ2VU2RIS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Python release announcement format

2021-12-15 Thread Yann Droneaud

Hi,


Have I missed something?


Having the SHA-2 256 in the release email makes it a bit more immutable: my 
mailbox is not
reachabable by the same people that can replace the release archives on the 
server.
Let's say it's adding a second factor of trust.

Regards.

--
Yann Droneaud
OPTEYA

___
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/TS5FDQTMKVS3CYOUABH4AHGVLZ3NL5LI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Antoine Pitrou


Hi Eric,

Did you try to take into account the envisioned project for adding a
"complete" GC and removing the GIL?

Regards

Antoine.


On Tue, 14 Dec 2021 10:12:07 -0700
Eric Snow  wrote:
> Hi all,
> 
> I'm still hoping to land a per-interpreter GIL for 3.11.  There is
> still a decent amount of work to be done but little of it will require
> solving any big problems:
> 
> * pull remaining static globals into _PyRuntimeState and PyInterpreterState
> * minor updates to PEP 554
> * finish up the last couple pieces of the PEP 554 implementation
> * maybe publish a companion PEP about per-interpreter GIL
> 
> There are also a few decisions to be made.  I'll open a couple of
> other threads to get feedback on those.  Here I'd like your thoughts
> on the following:
> 
> Do we need a PEP about per-interpreter GIL?
> 
> I haven't thought there would be much value in such a PEP.  There
> doesn't seem to be any decision that needs to be made.  At best the
> PEP would be an explanation of the project, where:
> 
> * the objective has gotten a lot of support (and we're working on
> addressing the concerns of the few objectors)
> * most of the required work is worth doing regardless (e.g. improve
> runtime init/fini, eliminate static globals)
> * the performance impact is likely to be a net improvement
> * it is fully backward compatible and the C-API is essentially unaffected
> 
> So the value of a PEP would be in consolidating an explanation of the
> project into a single document.  It seems like a poor fit for a PEP.
> 
> (You might wonder, "what about PEP 554?"  I purposefully avoided any
> discussion of the GIL in PEP 554.  It's purpose is to expose
> subinterpreters to Python code.)
> 
> However, perhaps I'm too close to it all.  I'd like your thoughts on the 
> matter.
> 
> Thanks!
> 
> -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/SRHY5LSROAGR5JRBYJP6LBETC4DBBFLO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Antoine Pitrou
On Wed, 15 Dec 2021 14:13:03 +0100
Antoine Pitrou  wrote:
> Hi Eric,
> 
> Did you try to take into account the envisioned project for adding a
> "complete" GC and removing the GIL?

Sorry, I was misremembering the details.  Sam Gross' proposal
(posted here on 07/10/2021) doesn't switch to a "complete GC", but it
changes reference counting to a more sophisticated scheme (which
includes immortalization of objects):

https://docs.google.com/document/d/18CXhDb1ygxg-YXNBJNzfzZsDFosB5e6BfnXLlejd9l0/edit

Regards

Antoine.

> 
> Regards
> 
> Antoine.
> 
> 
> On Tue, 14 Dec 2021 10:12:07 -0700
> Eric Snow  wrote:
> > Hi all,
> > 
> > I'm still hoping to land a per-interpreter GIL for 3.11.  There is
> > still a decent amount of work to be done but little of it will require
> > solving any big problems:
> > 
> > * pull remaining static globals into _PyRuntimeState and PyInterpreterState
> > * minor updates to PEP 554
> > * finish up the last couple pieces of the PEP 554 implementation
> > * maybe publish a companion PEP about per-interpreter GIL
> > 
> > There are also a few decisions to be made.  I'll open a couple of
> > other threads to get feedback on those.  Here I'd like your thoughts
> > on the following:
> > 
> > Do we need a PEP about per-interpreter GIL?
> > 
> > I haven't thought there would be much value in such a PEP.  There
> > doesn't seem to be any decision that needs to be made.  At best the
> > PEP would be an explanation of the project, where:
> > 
> > * the objective has gotten a lot of support (and we're working on
> > addressing the concerns of the few objectors)
> > * most of the required work is worth doing regardless (e.g. improve
> > runtime init/fini, eliminate static globals)
> > * the performance impact is likely to be a net improvement
> > * it is fully backward compatible and the C-API is essentially unaffected
> > 
> > So the value of a PEP would be in consolidating an explanation of the
> > project into a single document.  It seems like a poor fit for a PEP.
> > 
> > (You might wonder, "what about PEP 554?"  I purposefully avoided any
> > discussion of the GIL in PEP 554.  It's purpose is to expose
> > subinterpreters to Python code.)
> > 
> > However, perhaps I'm too close to it all.  I'd like your thoughts on the 
> > matter.
> > 
> > Thanks!
> > 
> > -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/HSPKKNQ7H24EPI2XPKKZLMXTREOB47FB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Skip Montanaro
It might be worth (re)reviewing Sam Gross's nogil effort to see how he
approached this:

https://github.com/colesbury/nogil#readme


He goes into plenty of detail in his design document about how he deals
with immortal objects. From that document:

Some objects, such as interned strings, small integers, statically
allocated PyTypeObjects, and the True, False, and None objects stay alive
for the lifetime of the program. These objects are marked as immortal by
setting the least-significant bit of the local reference count field (bit
0). The Py_INCREF and Py_DECREF macros are no-ops for these objects.


Skip
___
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/33E2H6JD46VWYBEEV7YB4EIUEZ5JODSQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Wed, Dec 15, 2021 at 2:50 AM Pablo Galindo Salgado
 wrote:
> One thing to consider: ideally, inmortal objects should not participate in 
> the GC. There is nothing inheritly wrong if they do but we would need to 
> update the GC (and therefore add more branching in possible hot paths) to 
> deal with these as the algorithm requires the refcount to be exact to 
> correctly compute the cycles.

That's a good point.  Do static types and the global singletons
already opt out of GC participation?

-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/ASIWOGWC5CKB3TNIFYS6767HEES5ATSP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Wed, Dec 15, 2021 at 2:42 AM Christian Heimes  wrote:
> Would it be possible to write the Py_INCREF() and Py_DECREF() macros in
> a way that does not depend on branching? For example we could use the
> highest bit of the ref count as an immutable indicator and do something like

As Antoine pointed out, wouldn't that cause too much cache
invalidation between threads, especially for None, True, and False.
That's the main reason I abandoned my previous effort
(https://github.com/ericsnowcurrently/cpython/pull/9).

-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/UA7CVGRI4N6ADOHDPMM4GC66XYKTW3KL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Tue, Dec 14, 2021 at 11:19 AM Eric Snow  wrote:
> The idea of objects that never get deallocated isn't new and has been
> explored here several times.  Not that long ago I tried it out by
> setting the refcount really high.  That worked.  Around the same time
> Eddie Elizondo at Facebook did something similar but modified
> Py_INCREF() and Py_DECREF() to keep the refcount from changing.  Our
> solutions were similar but with different goals in mind.  (Facebook
> wants to avoid copy-on-write in their pre-fork model.)

FTR, here are links to the above efforts:

* reducing CoW (Instagram): https://bugs.python.org/issue40255
* Eddie's PR: https://github.com/python/cpython/pull/19474
* my PR: https://github.com/python/cpython/pull/24828
* some other discussion: https://github.com/faster-cpython/ideas/issues/14

(I don't have a link to any additional work Eddie did to reduce the
performance penalty.)

-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/OUJHQY22BZY5TJXYGPQQOBTCLUWB6OVQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Pablo Galindo Salgado
All singletons do, AFAIK. And most static types that I can think of also
do, even the empty tuple.

On Wed, 15 Dec 2021 at 16:49, Eric Snow  wrote:

> On Wed, Dec 15, 2021 at 2:50 AM Pablo Galindo Salgado
>  wrote:
> > One thing to consider: ideally, inmortal objects should not participate
> in the GC. There is nothing inheritly wrong if they do but we would need to
> update the GC (and therefore add more branching in possible hot paths) to
> deal with these as the algorithm requires the refcount to be exact to
> correctly compute the cycles.
>
> That's a good point.  Do static types and the global singletons
> already opt out of GC participation?
>
> -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/3EAUAU5PF5YEHW4XXAVQGSLF4QEFCMJ6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Wed, Dec 15, 2021 at 4:03 AM Victor Stinner  wrote:
> The last time I saw a benchmark on immortal object, it was clearly 10%
> slower overall on the pyperformance benchmark suite. That's a major
> slowdown.

Yes, I plan on benchmarking the change as soon as we can run
pyperformance on main.

> > * abandon all hope
>
> I wrote https://bugs.python.org/issue39511 and
> https://github.com/python/cpython/pull/18301 to have per-interpreter
> None, True and False singletons.

Yeah, I took a similar approach in the alternative to immortal objects
that I prototyped.

> By the way, I made the _Py_IDENTIFIER() API and _PyUnicode_FromId()
> compatible with subinterpreters in Python 3.10. This change caused a
> subtle regression when using subintepreters (because an optimization
> made on an assumption on interned strings which is no longer true).
> The fix is trivial but I didn't wrote it yet:
> https://bugs.python.org/issue46006

FYI, I'm looking into statically allocating (and initializing) all the
string objects currently using _Py_IDENTIFIER().

-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/3XG4QY77MCRXEFUCJHB44RRIHFEM4MDD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Wed, Dec 15, 2021 at 8:16 AM Skip Montanaro  wrote:
> It might be worth (re)reviewing Sam Gross's nogil effort to see how he 
> approached this:

Yeah, there is good info in there.

-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/BRQQ4FKWPXIEBSPKR4G2UUC4U4LDF3OV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Eric Snow
On Wed, Dec 15, 2021 at 6:16 AM Antoine Pitrou  wrote:
> Did you try to take into account the envisioned project for adding a
> "complete" GC and removing the GIL?

Yeah.  I was going to start a separate thread about per-interpreter
GIL vs. no-gil, but figured I was already pushing my luck with 3
simultaneous related threads here. :)  It would definitely be covered
by the info doc/PEP.

-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/XHJ3PNBW23HXCT4BI3LXYFE4Q5NW576P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Tue, Dec 14, 2021 at 11:19 AM Eric Snow  wrote:
> There is one solution that would help both of the above in a nice way:
> "immortal" objects.

FYI, here are some observations that came up during some discussions
with the "faster-cpython" team today:

* immortal objects should probably only be immutable ones (other than
ob_refcnt, of course)
* GC concerns are less of an issue if a really high ref count (bit) is
used to identify immortal objects
* ob_refcnt is part of the public API (sadly), so using it to mark
immortal objects may be sensitive to interference
* ob_refcnt is part of the stable ABI (even more sadly), affecting any
solution using ref counts
* using the ref count isn't the only viable approach; another would be
checking the pointer itself
   + put the object in a specific section of static data and compare
the pointer against the bounds
   + this avoids loading the actual object data if it is immortal
   + for objects that are mostly treated as markers (e.g. None), this
could have a meaningful impact
   + not compatible with dynamically allocated 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/LVLFPOIOXM34NQ2G73BAXIRS4TIN74JV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Chris Angelico
On Thu, Dec 16, 2021 at 6:03 AM Eric Snow  wrote:
> * using the ref count isn't the only viable approach; another would be
> checking the pointer itself
>+ put the object in a specific section of static data and compare
> the pointer against the bounds
>+ this avoids loading the actual object data if it is immortal
>+ for objects that are mostly treated as markers (e.g. None), this
> could have a meaningful impact
>+ not compatible with dynamically allocated objects
>

Sorry if this is a dumb question, but would it be possible to solve
that last point with an immortal arena [1] from which immortal objects
could be allocated? None/True/False could be allocated there, but so
could anything that is more dynamic, if it's decided as important
enough. It would still be possible to recognize them by pointer (since
the immortal arena would be a specific block of memory).

ChrisA

[1] That sounds like something from Norse mythology, actually
___
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/IQH4RXOBKFMABYU2KPE24YANUBMLE6UW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Chris Angelico
On Thu, Dec 16, 2021 at 7:03 AM Eric Snow  wrote:
>
> On Wed, Dec 15, 2021 at 12:18 PM Chris Angelico  wrote:
> > Sorry if this is a dumb question, but would it be possible to solve
> > that last point with an immortal arena [1] from which immortal objects
> > could be allocated? None/True/False could be allocated there, but so
> > could anything that is more dynamic, if it's decided as important
> > enough. It would still be possible to recognize them by pointer (since
> > the immortal arena would be a specific block of memory).
>
> That's an interesting idea.  An immortal arena would certainly be one
> approach to investigate.
>
> However, I'm not convinced there is enough value to justify going out
> of our way to allow dynamically allocated objects to be immortal.
> Keep in mind that the concept of immortal objects would probably not
> be available outside the internal API, and, internally, any objects we
> want to be immortal will probably be statically allocated.
>
That makes sense. Thanks.

ChrisA
___
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/HMRUXVGTZHHJKSS2WGPPT2UURPGQHCWF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Eric Snow
On Wed, Dec 15, 2021 at 12:18 PM Chris Angelico  wrote:
> Sorry if this is a dumb question, but would it be possible to solve
> that last point with an immortal arena [1] from which immortal objects
> could be allocated? None/True/False could be allocated there, but so
> could anything that is more dynamic, if it's decided as important
> enough. It would still be possible to recognize them by pointer (since
> the immortal arena would be a specific block of memory).

That's an interesting idea.  An immortal arena would certainly be one
approach to investigate.

However, I'm not convinced there is enough value to justify going out
of our way to allow dynamically allocated objects to be immortal.
Keep in mind that the concept of immortal objects would probably not
be available outside the internal API, and, internally, any objects we
want to be immortal will probably be statically allocated.

-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/I2ZG4J577Q4CDWXQHYCOMOFMPJPP5XJT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Guido van Rossum
On Wed, Dec 15, 2021 at 6:04 AM Antoine Pitrou  wrote:

> On Wed, 15 Dec 2021 14:13:03 +0100
> Antoine Pitrou  wrote:
>
> > Did you try to take into account the envisioned project for adding a
> > "complete" GC and removing the GIL?
>
> Sorry, I was misremembering the details.  Sam Gross' proposal
> (posted here on 07/10/2021) doesn't switch to a "complete GC", but it
> changes reference counting to a more sophisticated scheme (which
> includes immortalization of objects):
>
>
> https://docs.google.com/document/d/18CXhDb1ygxg-YXNBJNzfzZsDFosB5e6BfnXLlejd9l0/edit
>

A note about this: Sam's immortalization covers exactly the objects that
Eric is planning to move into the interpreter state struct: "such as
interned strings, small integers, statically allocated PyTypeObjects, and
the True, False, and None objects". (Well, he says "such as" but I think so
does Eric. :-)

Sam's approach is to use the lower bit of the ob_refcnt field to indicate
immortal objects. This would not work given the stable ABI (which has
macros that directly increment and decrement the ob_refcnt field). In fact,
I think that Sam's work doesn't preserve the stable ABI at all. However,
setting a very high bit (the bit just below the sign bit) would probably
work. Say we're using 32 bits. We use the value 0x_6000_ as the initial
refcount for immortal objects. The stable ABI will sometimes increment
this, sometimes decrement it. But as long as the imbalance is less than
0x_2000_, the refcount will remain in the inclusive range [
0x_4000_ , 0x_7FFF_ ] and we can test for immortality by testing a
single bit:

if (o->ob_refcnt & 0x_4000_)

I don't know how long that would take, but I suspect that a program that
just increments the refcount relentlessly would have to run for hours
before hitting this range. On a 64-bit machine the same approach would
require years to run before a refcount would exceed the maximum allowable
imbalance. (These estimates are from Mark Shannon.)

Another potential issue is that there may be some applications that take
refcounts at face value (perhaps obtained using sys.getrefcount()). These
would find that immortal objects have a very large refcount, which might
surprise them. But technically a very large refcount is totally valid, and
the kinds of objects that we plan to immortalize are all widely shared --
who cares if the refcount for None is 5000 or 1610612736? As long as the
refcount of *mortal* objects is the same as it was before, this shouldn't
be a problem.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
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/FKVH4ZDGALGYMTEROJAEM4XFKNE662S6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Eric Snow
On Tue, Dec 14, 2021 at 10:12 AM Eric Snow  wrote:
> * it is fully backward compatible and the C-API is essentially unaffected

Hmm, this is a little misleading.  It will definitely be backward
incompatible for extension modules that don't work under multiple
subinterpreters (or rely on the GIL to protect global state).  Hence
that other thread I started. :)

-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/UDMQXP6GO5SYJGHKHX2W4VRSNAZ55PMI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Christopher Barker
On Wed, Dec 15, 2021 at 3:00 PM Guido van Rossum  wrote:


> who cares if the refcount for None is 5000 or 1610612736? As long as the
> refcount of *mortal* objects is the same as it was before, this shouldn't
> be a problem.
>

indeed:

$ python -c "import sys; print(sys.getrefcount(None))"
4110

and a newly started iPython session:

In [2]: sys.getrefcount(None)
Out[2]: 28491

It does seem a bit silly to actually be tracking that refcount :-)

-CHB

-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/36N4I4CJ53OR3CLDJSJUIXEAS3NIFURP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Pablo Galindo Salgado
>> It does seem a bit silly to actually be tracking that refcount :-)

Not that silly. It can easily help in C extensions to detect wrong DECREF
calls:

>> import ctypes
>> non = ctypes.c_long.from_address(id(None))
>> non.value = 10
>>
Fatal Python error: none_dealloc: deallocating None
Python runtime state: finalizing (tstate=0x55c66cf263f0)

Current thread 0x7f4afa383740 (most recent call first):
  
[1]635685 abort (core dumped)  python

On Thu, 16 Dec 2021 at 00:31, Christopher Barker 
wrote:

> On Wed, Dec 15, 2021 at 3:00 PM Guido van Rossum  wrote:
>
>
>> who cares if the refcount for None is 5000 or 1610612736? As long as the
>> refcount of *mortal* objects is the same as it was before, this shouldn't
>> be a problem.
>>
>
> indeed:
>
> $ python -c "import sys; print(sys.getrefcount(None))"
> 4110
>
> and a newly started iPython session:
>
> In [2]: sys.getrefcount(None)
> Out[2]: 28491
>
> It does seem a bit silly to actually be tracking that refcount :-)
>
> -CHB
>
> --
> Christopher Barker, PhD (Chris)
>
> Python Language Consulting
>   - Teaching
>   - Scientific Software Development
>   - Desktop GUI and Web Development
>   - wxPython, numpy, scipy, Cython
> ___
> 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/36N4I4CJ53OR3CLDJSJUIXEAS3NIFURP/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/QNFHXI2IQYU7RDTUPMRITEPKNEXACQWK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Neil Schemenauer

On 2021-12-15 2:57 p.m., Guido van Rossum wrote:

But as long as the imbalance is less than 0x_2000_, the refcount 
will remain in the inclusive range [ 0x_4000_ , 0x_7FFF_ ] and 
we can test for immortality by testing a single bit:


if (o->ob_refcnt & 0x_4000_)


Could we have a full GC pass reset those counts to make it even more 
unlikely to get out of bounds?


Allocating immortal objects from a specific memory region seems like 
another idea worth pursuing.  It seems mimalloc has the ability to 
allocate pools aligned to certain large boundaries. That takes some 
platform specific magic.   If we can do that, the test for immortality 
is pretty cheap.  However, if you can't allocate them at a fixed region 
determined at compile time, I don't think you can match the performance 
of the code above. Maybe it helps that you could determine immortality 
by looking at the PyObject pointer and without loading the ob_refcnt 
value from memory?  You would do something like:


if (((uintptr_t)o) & _Py_immortal_mask)

The _Py_immortal_mask value would not be known at compile time but would 
be a global constant.  So, it would be cached by the CPU.
___
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/BESETUOZGP6NZ37F32DUBEYZ4BUK2UWD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Nathaniel Smith
On Wed, Dec 15, 2021 at 3:07 AM Victor Stinner  wrote:
> I wrote https://bugs.python.org/issue39511 and
> https://github.com/python/cpython/pull/18301 to have per-interpreter
> None, True and False singletons. My change is backward compatible on
> the C API: you can still use "Py_None" in your C code. The code gets
> the singleton object from the current interpreter with a function
> call:
>
> #define Py_None Py_GetNone()
>
> Py_GetNone() is implemented as: "return _PyInterpreterState_GET()->none;"

It's backward compatible for the C API, but not for the stable C ABI
-- that exports Py_None directly as a symbol.

You also need a solution for all the static global PyTypeObjects in C
extensions. I don't think there's any API-compatible way to make those
heap-allocated.

-n

-- 
Nathaniel J. Smith -- https://vorpus.org
___
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/HS3NENZXKYSBCN4OVUOZ2CUX55Z5CXG5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Guido van Rossum
(I just realized that we started discussing details of immortal objects in
the wrong thread -- this is Eric's overview thread, there's a separate
thread on immortal objects. But alla, I'll respond here below.)

On Wed, Dec 15, 2021 at 5:05 PM Neil Schemenauer  wrote:

> On 2021-12-15 2:57 p.m., Guido van Rossum wrote:
>
> But as long as the imbalance is less than 0x_2000_, the refcount will
> remain in the inclusive range [ 0x_4000_ , 0x_7FFF_ ] and we can
> test for immortality by testing a single bit:
>
> if (o->ob_refcnt & 0x_4000_)
>
> Could we have a full GC pass reset those counts to make it even more
> unlikely to get out of bounds?
>
Maybe, but so far these are all immutable singletons that aren't linked
into the GC at all. Of course we could just add extra code to the GC code
that just resets all these refcounts, but since there are ~260 small
integers that might slow things down more than we'd like. More testing is
required. Maybe we can get away with doing nothing on 64-bit machines but
we'll have to slow down a tad for 32-bit -- that would be acceptable (since
the future is clearly 64-bit).


> Allocating immortal objects from a specific memory region seems like
> another idea worth pursuing.  It seems mimalloc has the ability to allocate
> pools aligned to certain large boundaries.  That takes some platform
> specific magic.   If we can do that, the test for immortality is pretty
> cheap.  However, if you can't allocate them at a fixed region determined at
> compile time, I don't think you can match the performance of the code
> above.  Maybe it helps that you could determine immortality by looking at
> the PyObject pointer and without loading the ob_refcnt value from memory?
> You would do something like:
>
> if (((uintptr_t)o) & _Py_immortal_mask)
>
> The _Py_immortal_mask value would not be known at compile time but would
> be a global constant.  So, it would be cached by the CPU.
>
Very clever.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
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/6WVBFSZOI2JFGBKPPCSIXOCDUZK5G5EO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Guido van Rossum
On Wed, Dec 15, 2021 at 2:57 PM Guido van Rossum  wrote:

>
> I don't know how long that would take, but I suspect that a program that
> just increments the refcount relentlessly would have to run for hours
> before hitting this range. On a 64-bit machine the same approach would
> require years to run before a refcount would exceed the maximum allowable
> imbalance. (These estimates are from Mark Shannon.)
>

Hm, not quite. I modified a fast builtin to incref its argument, and then I
called it in a `while True` loop, interrupted, and timed it. This did
~24,000,000 INCREFs/second. This would hit 0x_2000_ in about 9 minutes.
And I wasn't even trying that hard -- I could have written the loop in C.
(I did comment out an audit call though. :-) The same loop on 64-bit would
take 1700 years to reach the limit, so we're safe there.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
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/2PQVABDBGJEKRBGVLOQEFY72KZO66W3J/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: subinterpreters and their possible impact on large extension projects

2021-12-15 Thread Jim J. Jewett
> In Python 3.11, Python still implements around 100 types as "static
> types" which are not compatible with subinterpreters, like
> &PyLong_Type and &PyUnicode_Type. I opened
> https://bugs.python.org/issue40601 about these static types, but it
> seems like changing it may break the C API *and* the stable ABI (maybe
> a clever hack will avoid that).

If sub-interpreters each need their own copy of even immutable built-in types, 
then what advantage do they have over separate processes?

-jJ
___
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/B7WO5B426HBTG6KZVKQXTJSBQL2S2ILQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Jim J. Jewett
Immortal objects shouldn't be reclaimed by garbage collection, but they still 
count as potential external roots for non-cyclic liveness.

-jJ
___
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/FMIUHY6K3UUAUTK7GDTTOO4ULXO74QMP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Jim J. Jewett
How common is it to reload a module in production code?

It seems like "object created at the module level" (excluding __main__) is at 
least as good of an heuristic for immortality as "string that meets the 
syntactic requirements for an identifier".  Perhaps also anything created as 
part of class creation (as opposed to instance initialization).

-jJ
___
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/F3IEICCQTKGZMRX3L4JS4NEZZNXVMZGA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: "immortal" objects and how they would help per-interpreter GIL

2021-12-15 Thread Guido van Rossum
On Wed, Dec 15, 2021 at 6:57 PM Jim J. Jewett  wrote:

> Immortal objects shouldn't be reclaimed by garbage collection, but they
> still count as potential external roots for non-cyclic liveness.
>

So everything referenced by an immortal object should also be made immortal
-- even its type. Hence immortal objects must be immutable. (There's an
issue with making types immutable that we need to address though.)


-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
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/TMAU4LJX2R3JTULXFYZWCWHGWFUROMWK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Itamar O
On Wed, Dec 15, 2021 at 6:21 PM Guido van Rossum  wrote:

> On Wed, Dec 15, 2021 at 2:57 PM Guido van Rossum  wrote:
>
>>
>> I don't know how long that would take, but I suspect that a program that
>> just increments the refcount relentlessly would have to run for hours
>> before hitting this range. On a 64-bit machine the same approach would
>> require years to run before a refcount would exceed the maximum allowable
>> imbalance. (These estimates are from Mark Shannon.)
>>
>
> Hm, not quite. I modified a fast builtin to incref its argument, and then
> I called it in a `while True` loop, interrupted, and timed it. This did
> ~24,000,000 INCREFs/second. This would hit 0x_2000_ in about 9 minutes.
> And I wasn't even trying that hard -- I could have written the loop in C.
> (I did comment out an audit call though. :-) The same loop on 64-bit would
> take 1700 years to reach the limit, so we're safe there.
>

Similar 32-bit vs 64-bit overflow estimates were made by Victor Stinner in
the dict version tag PEP 509
https://www.python.org/dev/peps/pep-0509/#integer-overflow

tldr 4sec on 32-bit and 584 years on 64-bit
Granted, the risk there is only for *exactly* `2 ** (Nbits)` increments.


>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him **(why is my pronoun here?)*
> 
> ___
> 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/2PQVABDBGJEKRBGVLOQEFY72KZO66W3J/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/QPZMYD3CWSML5IIWODVDZXARAQ3MYRX3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: my plans for subinterpreters (and a per-interpreter GIL)

2021-12-15 Thread Steven D'Aprano
On Wed, Dec 15, 2021 at 02:57:46PM -0800, Guido van Rossum wrote:

> Another potential issue is that there may be some applications that take
> refcounts at face value (perhaps obtained using sys.getrefcount()). These
> would find that immortal objects have a very large refcount, which might
> surprise them. But technically a very large refcount is totally valid, and
> the kinds of objects that we plan to immortalize are all widely shared --
> who cares if the refcount for None is 5000 or 1610612736? As long as the
> refcount of *mortal* objects is the same as it was before, this shouldn't
> be a problem.

I agree with your reasoning. But can we agree to document the presence 
and interpretation of the magic bit, so that if anyone actually does 
care (for whatever reason, good bad or indifferent) they can mask off 
the immortal bit to get the real ref num?

Or maybe even have getrefcount() automatically mask the bit off. If we 
reserve the bit as the immortal bit, then is there any reason to keep 
that bit visible when returning refcounts?

-- 
Steve
___
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/DV4OYEFTJV6XLVYLIJBYR76SPTCHNTUT/
Code of Conduct: http://python.org/psf/codeofconduct/