[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Larry Hastings


On 11/13/19 5:52 AM, Victor Stinner wrote:

Le mer. 13 nov. 2019 à 14:28, Larry Hastings  a écrit :

I did exactly that in the Gilectomy prototype.  Pulling it out of TLS was too 
slow,

What do you mean? Getting tstate from a TLS was a performance
bottleneck by itself? Reading a TLS variable seems to be quite
efficient.


I'm pretty sure you understand the sentence "Pulling it out of TLS was 
too slow".  At the time CPython used the POSIX APIs for accessing thread 
local storage, and I didn't know about and therefore did not try this 
"__thread" GCC extension.  I do remember trying some other API that was 
purported to be faster--maybe a GCC library function for faster TLS 
access?--but I didn't get that to work either before I gave up on it out 
of frustration.


Also, I dimly recall that I moved several things from globals into the 
ThreadState structure, and probably added one or two of my own.  So 
nearly every function call was referencing ThreadState at one point or 
another.  Passing it as a parameter was a definite win over calling the 
POSIX TLS APIs.


I also took the opportunity to pass my "reference count manager" data as 
a separate parameter, which again was per-thread and again was a major 
win at the time.



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


[Python-Dev] Re: Implementation of PEP-0604

2019-11-13 Thread Richard Eames
Thanks for the encouragement! 

I've been working some more on it since I had some more free cycles in the last 
few days and I think I've got to the limit of my capabilities. I think I've got 
it to a point where it needs more eyes because my experience level writing code 
in the python interpreter is pretty low, so I know that I have holes in there, 
especially around using INCREF/DECREF. 
I'm currently stuck on 3 things:

1. repr( pickle.loads( pickle.dumps(int | str) ) ) causes an infinite recursion 
that I can't figure out. I might end up re-specializing `repr()` again since it 
isn't defined in the PEP.

2.
- `None | "forwardref"` and `None | None`
- `"forwardref" | None` and `"forwardRefA" | "forwardRefB"` 
I've had a go at adding a `type.__ror__` as suggested by GvR, but I think I'm 
missing something.

3. type parameters
- I'm not sure how to handle this:
```
MaybeT = None | "T" # creates shadow union
T = TypeVar('T')
maybe_int = MaybeT[int] # should this stay in shadow land, or go back to 
typing.py
isinstance(1, maybe_int)
isinstance(1, MaybeT[int])
```
I have a couple options for this:
- implement the type substitution in c; which can be done, but feels like 
overkill?
- store the type parameters on the shadow object and vivify when needed (which 
will end up being in the isinstance call)
- implement the __getitem__ as a call into the typing.py library and promote as 
it's requested. This is how I've currently implemented it.

I'm happy to keep going on this if/when needed,

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


[Python-Dev] Re: Nominations for the 2019 Steering Council Election are open until Friday.

2019-11-13 Thread Carol Willing
Thanks Thomas. If there are any questions, I'm happy to do my best to
answer those too.

On Wed, Nov 13, 2019 at 3:39 AM Thomas Wouters  wrote:

>
> Perhaps this should've been announced a little more widely: we have
> upcoming Steering Council elections, and nominations close soon -- end of
> day *this Friday*. Five seats need to be filled. (We have four nominations
> so far, but I have no idea how many people are gearing up to nominate in
> the next couple of days.)
>
> Nominees *do not need to be core developers*, although a core developer
> has to do the nominating. Brett Cannon and Carol Willing have posted about
> what the work entails:
>
> https://snarky.ca/what-its-like-to-be-on-the-python-steering-council/
> https://www.willingconsulting.com/post/2019-11-02-python-steering-retro/
>
> If you think you might be interested but you're not a core developer, or
> you're just not comfortable self-nominating, please feel free to talk to me
> (or other core developers you might know). If you're not sure if you'd have
> a useful contribution -- well, we can talk about that, too :)
>
> -- Forwarded message -
> From: Ewa Jodlowska 
> Date: Fri, Nov 1, 2019 at 1:40 PM
> Subject: [python-committers] Nominations for the 2019 Steering Council
> Election are now open.
> To: 
>
>
> Hello!
>
> Per PEP 13, members of the Committers group can post to the "Steering
> Council Nominations"
>  category on Discourse to nominate a person (
> https://discuss.python.org/t/2019-steering-council-nominations-are-now-open/2561).
> All users are able to reply.
>
> Nominations should be posted as a Topic with the name "Steering Council
> nomination: " and tagged with the election tag.
>
> All Posts and Replies in this category will be moderated, so there may be
> some delay before they appear.
>
> Thank you,
>
> Ernest & Ewa
>
> ---
> *As a non-profit organization, the PSF depends on sponsorships and
> donations to support the Python community. Check out our Annual Impact
> Report for more details: https://www.python.org/psf/annual-report/2019/
> *
> *Please contribute to PSF; we can't continue our work without your
> support! https://www.python.org/psf/donations/
> *
> ___
> python-committers mailing list -- python-committ...@python.org
> To unsubscribe send an email to python-committers-le...@python.org
> https://mail.python.org/mailman3/lists/python-committers.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-committ...@python.org/message/ZJ4V2KPFE6DJO4GONP7YV2QCHBM6UUY7/
> Code of Conduct: https://www.python.org/psf/codeofconduct/
>
>
> --
> Thomas Wouters 
>
> Hi! I'm an email virus! Think twice before sending your email to help me
> spread!
> ___
> 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/3A3NDLUTA47FXIP3QKTBJF556372MOO6/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
*Carol Willing*

Willing Consulting 

*Signature strengths*
*Empathy - Relator - Ideation - Strategic - Learner*
___
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/KN3S5TJTPIJQIUGIQJN6OYFB7MXQLIJN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Jim J. Jewett
I wouldn't worry too much about the the Singletons in this issue; they could be 
solved in any of several ways, all of which would be improvements conceptually 
-- if performance and backwards compatibility were resolved.

In theory, the incr/decr pair should be delegated to the memory store, with 
Petr's suggestion of immortal immutables being one example.  The catch is that 
the current scheme is really fast in the normal case; even hardcoding just 
True/False/None to magic addresses might be slower.  

You don't have to solve that just to speed up access to state variables that 
are not exposed directly to python code.
___
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/3KDVELTYRTY72RL7X24VZHBXSKAOY2YH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Victor Stinner
Petr, Eric: sure, my question is only about the internal C functions.
I have no plan to change the existing C API.

Le mer. 13 nov. 2019 à 14:52, Eric V. Smith  a écrit :
> The last time we discussed this, there was pushback due to performance
> concerns. I don't recall if that was actually measured, or just a vague
> unease.

Maybe I was the one who raised a concern about the atomic variable
performance. But I never ran a benchmark on that.


> I agree with Petr that not breaking existing
> APIs is of course critical. A parallel set of APIs is needed. But the
> existing APIs should become thin wrappers, until Python 5000 (aka never)
> when they can go away.

There is a project of a new C API for Python:
https://github.com/pyhandle/hpy

I suggested to add a mandatory "context" parameter since day 1. See
the current API draft, it has a "ctx" argument:
https://github.com/pyhandle/hpy/blob/3266dc295b0be20b41c99f4f4e944d117b3fc875/api.md

Example: "HPy v = HPy_Something(ctx);"

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


[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Victor Stinner
Le mer. 13 nov. 2019 à 14:28, Larry Hastings  a écrit :
> I did exactly that in the Gilectomy prototype.  Pulling it out of TLS was too 
> slow,

What do you mean? Getting tstate from a TLS was a performance
bottleneck by itself? Reading a TLS variable seems to be quite
efficient.

Mark Shannon wrote: "The current means of accessing the thread state
does seem rather convoluted, whereas accessing from a thread local is
quite efficient (at least with GCC) https://godbolt.org/z/z-vNPN "
https://github.com/python/cpython/pull/17052#issuecomment-552538438

Copy of his C code:
"""
extern __thread int extern_tl;
int get_extern_thread_local(void) {
return extern_tl;
}

__thread int tl;
int get_thread_local(void) {
return tl;
}
"""

And the generated assembly (by godbolt.org service):
"""
get_extern_thread_local():
mov rax, QWORD PTR extern_tl@gottpoff[rip]
mov eax, DWORD PTR fs:[rax]
ret

get_thread_local():
mov eax, DWORD PTR fs:tl@tpoff
ret

tl:
.zero 4
"""

TLS variable read is basically one or two MOV in the Intel x86
assembly (using GCC 9.2).

With a friend, I looked at the assembly to read and write atomic
variables. In short, only the write requires a memory fence, whereas
the read is basically just a MOV (again, in Intel x86).

#define _PyRuntimeState_GetThreadState(runtime) \

((PyThreadState*)_Py_atomic_load_relaxed(&(runtime)->gilstate.tstate_current))
#define _PyThreadState_GET() _PyRuntimeState_GetThreadState(&_PyRuntime)

_PyThreadState_GET() uses "_Py_atomic_load_relaxed". I'm not used to
C99 atomic conventions. The "memory_order_relaxed" documentation says:

"Relaxed operation: there are no synchronization or ordering
constraints imposed on other reads or writes, only this operation's
atomicity is guaranteed (see Relaxed ordering below)"

Note: I'm not even sure why Python currently uses an atomic operation.
Not why just a regular global variable? By if we change something, I
would prefer to move to a TLS variable instead, to support
subinterpreters.

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


[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Eric V. Smith

On 11/12/2019 5:03 PM, Victor Stinner wrote:

Hi,

Are you ok to modify internal C functions to pass explicitly tstate?


The last time we discussed this, there was pushback due to performance 
concerns. I don't recall if that was actually measured, or just a vague 
unease.


I've long advocated (mostly to myself, and Larry when he would listen!) 
that we should do this. I agree with Petr that not breaking existing 
APIs is of course critical. A parallel set of APIs is needed. But the 
existing APIs should become thin wrappers, until Python 5000 (aka never) 
when they can go away.


And this not only helps with being explicit, it should help with 
testing. No more depending on some hidden global state.


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


[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Larry Hastings


On 11/12/19 2:03 PM, Victor Stinner wrote:

Hi,

Are you ok to modify internal C functions to pass explicitly tstate?


I did exactly that in the Gilectomy prototype.  Pulling it out of TLS 
was too slow, and storing it in a global wouldn't work with multiple 
actually-concurrent threads.



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


[Python-Dev] Re: Pass the Python thread state to internal C functions

2019-11-13 Thread Petr Viktorin

On 2019-11-12 23:03, Victor Stinner wrote:

Hi,

Are you ok to modify internal C functions to pass explicitly tstate?


In short, yes, but:
- don't make things slower :)
- don't break the public API or the stable ABI


I'm a fan of explicitly passing state everywhere, rather than keeping it 
in "global" variables.


Currently, surprisingly many internal functions do a PyThreadState_GET 
for themselves, then call another function that does the same. That's 
wasteful, but impossible to change in the public API.
Your changes (of which I only saw a very limited subset) seem to follow 
a simple rule: public API functions call PyThreadState_GET, and then 
call internal functions that pass it around.
That's sounds beautifully easy to explain! Later, we'll just need to 
find a way to make the tstate API public (and opt-in).



The "per-interpreter None", however, is a different issue. I don't see 
how that can be done without breaking the stable ABI. I still think 
immortal immutable objects could be shared across interpreters.






--

I started to modify internal C functions to pass explicitly "tstate"
when calling C functions: the Python thread state (PyThreadState).
Example of C code (after my changes):

 if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
 return NULL;
 }
 PyObject *result = (*call)(callable, args, kwargs);
 _Py_LeaveRecursiveCall(tstate);
 return _Py_CheckFunctionResult(tstate, callable, result, NULL);

In Python 3.8, the tstate is implicit:

 if (Py_EnterRecursiveCall(" while calling a Python object")) {
 return NULL;
 }
 PyObject *result = (*call)(callable, args, kwargs);
 Py_LeaveRecursiveCall();
 return _Py_CheckFunctionResult(callable, result, NULL);

There are different reasons to pass explicitly tstate, but my main
motivation is to rework Python code base to move away from implicit
global states to states passed explicitly, to implement the PEP 554
"Multiple Interpreters in the Stdlib". In short, the final goal is to
run multiple isolated Python interpreters in the same process: run
pure Python code on multiple CPUs in parallel with a single process
(whereas multiprocessing runs multiple processes).

Currently, subinterpreters are a hack: they still share a lot of
things, the code base is not ready to implement isolated interpreters
with one "GIL" (interpreter lock) per interpreter, and to run multiple
interpreters in parallel. Many _PyRuntimeState fields (the global
_PyRuntime variable) should be moved to PyInterpreterState (or maybe
PyThreadState): per interpreter.

Another simpler but more annoying example are Py_None and Py_True
singletons which are globals. We cannot share these singletons between
interpreters because updating their reference counter would be a
performance bottleneck. If we put a "superglobal-GIL" to ensure that
Py_None reference counter remains consistent, it would basically
"serialize" all threads, rather than running them in parallel.

The idea of passing tstate to internal C functions is to prepare code
to get the per-interpreter None from tstate.

tstate is basically the "root" to access all states which are per
interpreter. For example, PyInterpreterState can be read from
tstate->interp.

Right now, tstate is only passed to a few functions, but you should
expect to see it passed to way more functions later, once more
structures will be moved to PyInterpreterState.

--

On my latest merged PR 17052 ("Add _PyObject_VectorcallTstate()"),
Mark Shannon wrote: "I don't see how this could ever be faster, nor do
I see how it is more correct."
https://github.com/python/cpython/pull/17052#issuecomment-552538438

Currently, tstate is get using these internal APIs:

#define _PyRuntimeState_GetThreadState(runtime) \
 
((PyThreadState*)_Py_atomic_load_relaxed(&(runtime)->gilstate.tstate_current))
#define _PyThreadState_GET() _PyRuntimeState_GetThreadState(&_PyRuntime)

or using public APIs:

PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
#define PyThreadState_GET() PyThreadState_Get()

I dislike _PyThreadState_GET() for 2 reasons:

* it relies on the _PyRuntime global variable: I would prefer to avoid
global variables
* it uses an atomic operation which can become a perofrmance issue
when more and more code will require tstate

--

An alternative would be to use PyGILState_GetThisThreadState() which
uses a thread local state (TLS) variable to get the Python thread
state ("tstate"), rather that _PyRuntime atomic variable. Except that
the PyGILState API doesn't support subinterpreters yet :-(

https://bugs.python.org/issue15751 "Support subinterpreters in the GIL
state API" is open since 2012.

Note: While the GIL is released, _PyThreadState_GET() is NULL, whereas
PyGILState_GetThisThreadState() is non-NULL.

--

Links:

* https://pythoncapi.readthedocs.io/runtime.html : my notes on moving
globals to per interpreter states
* 

[Python-Dev] Nominations for the 2019 Steering Council Election are open until Friday.

2019-11-13 Thread Thomas Wouters
Perhaps this should've been announced a little more widely: we have
upcoming Steering Council elections, and nominations close soon -- end of
day *this Friday*. Five seats need to be filled. (We have four nominations
so far, but I have no idea how many people are gearing up to nominate in
the next couple of days.)

Nominees *do not need to be core developers*, although a core developer has
to do the nominating. Brett Cannon and Carol Willing have posted about what
the work entails:

https://snarky.ca/what-its-like-to-be-on-the-python-steering-council/
https://www.willingconsulting.com/post/2019-11-02-python-steering-retro/

If you think you might be interested but you're not a core developer, or
you're just not comfortable self-nominating, please feel free to talk to me
(or other core developers you might know). If you're not sure if you'd have
a useful contribution -- well, we can talk about that, too :)

-- Forwarded message -
From: Ewa Jodlowska 
Date: Fri, Nov 1, 2019 at 1:40 PM
Subject: [python-committers] Nominations for the 2019 Steering Council
Election are now open.
To: 


Hello!

Per PEP 13, members of the Committers group can post to the "Steering
Council Nominations"
 category on Discourse to nominate a person (
https://discuss.python.org/t/2019-steering-council-nominations-are-now-open/2561).
All users are able to reply.

Nominations should be posted as a Topic with the name "Steering Council
nomination: " and tagged with the election tag.

All Posts and Replies in this category will be moderated, so there may be
some delay before they appear.

Thank you,

Ernest & Ewa

---
*As a non-profit organization, the PSF depends on sponsorships and
donations to support the Python community. Check out our Annual Impact
Report for more details: https://www.python.org/psf/annual-report/2019/
*
*Please contribute to PSF; we can't continue our work without your
support! https://www.python.org/psf/donations/
*
___
python-committers mailing list -- python-committ...@python.org
To unsubscribe send an email to python-committers-le...@python.org
https://mail.python.org/mailman3/lists/python-committers.python.org/
Message archived at
https://mail.python.org/archives/list/python-committ...@python.org/message/ZJ4V2KPFE6DJO4GONP7YV2QCHBM6UUY7/
Code of Conduct: https://www.python.org/psf/codeofconduct/


-- 
Thomas Wouters 

Hi! I'm an email virus! Think twice before sending your email to help me
spread!
___
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/3A3NDLUTA47FXIP3QKTBJF556372MOO6/
Code of Conduct: http://python.org/psf/codeofconduct/