Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorder some fields to facilitate out-of-process inspection #106140

Closed
pablogsal opened this issue Jun 27, 2023 · 3 comments
Closed

Reorder some fields to facilitate out-of-process inspection #106140

pablogsal opened this issue Jun 27, 2023 · 3 comments

Comments

@pablogsal
Copy link
Member

pablogsal commented Jun 27, 2023

Some of the relevant fields in the interpreter state and the frame state in 3.12 are very challenging to fetch from out of process tools because they are in offsets that depend on compilation or platform variables that are different in different platforms. Not only that but they require the tools to copy a huge amount of intermediate structures making the whole thing very verbose.

As an example, this is the list of stuff that needs to be copied so out-of-process debuggers can fetch the interpreters, runtime state and thread list:

https://gist.github.com/godlygeek/271951b20bb4c3783c2dd7c80908b116

With a simple reordering, that would shrink this to

https://gist.github.com/godlygeek/341ce879a638c0fece9d0081d63e5ad9

For the interpreter state is also quite bad. Here is the things that need to be copied:

https://gist.github.com/godlygeek/2468ff3d0f648a1aca7a8305bad7f825

Not only that, but this depends on the compile-time value of all of this:

 int PYSTACK_SIZEOF_VOID_P = sizeof(void*);
 int ALIGNMENT = PYSTACK_SIZEOF_VOID_P > 4 ? 16 : 8;
 int SMALL_REQUEST_THRESHOLD = 512;
 int NB_SMALL_SIZE_CLASSES   = (SMALL_REQUEST_THRESHOLD / ALIGNMENT);
 int OBMALLOC_USED_POOLS_SIZE = (2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8);

 int USE_LARGE_ARENAS = PYSTACK_SIZEOF_VOID_P > 4;
 int ARENA_BITS = USE_LARGE_ARENAS ? 20 : 18;
 int ARENA_SIZE = 1 << ARENA_BITS;
 int ARENA_SIZE_MASK = ARENA_SIZE - 1;

 int POINTER_BITS = 8 * PYSTACK_SIZEOF_VOID_P;
 int IGNORE_BITS = 0;
 int USE_INTERIOR_NODES = PYSTACK_SIZEOF_VOID_P > 4;
 int ADDRESS_BITS = (POINTER_BITS - IGNORE_BITS);
 int INTERIOR_BITS = USE_INTERIOR_NODES ? ((ADDRESS_BITS - ARENA_BITS + 2) / 3) : 0;

 int MAP_TOP_BITS = INTERIOR_BITS;
 int MAP_TOP_LENGTH = (1 << MAP_TOP_BITS);
 int MAP_TOP_MASK = (MAP_TOP_LENGTH - 1);

 int MAP_MID_BITS = INTERIOR_BITS;
 int MAP_MID_LENGTH = (1 << MAP_MID_BITS);

 int MAP_BOT_BITS = (ADDRESS_BITS - ARENA_BITS - 2 * INTERIOR_BITS);
 int MAP_BOT_LENGTH = (1 << MAP_BOT_BITS);

 int WITH_PYMALLOC_RADIX_TREE = 1;
 int USE_LARGE_POOLS = USE_LARGE_ARENAS ? WITH_PYMALLOC_RADIX_TREE : 0;
 int POOL_BITS = USE_LARGE_POOLS ? 14 : 12;
 int POOL_SIZE = (1 << POOL_BITS);
 int MAX_POOLS_IN_ARENA = (ARENA_SIZE / POOL_SIZE);

If the user changes any of these (like WITH_PYMALLOC_RADIX_TREE) when compiling Python, then the tools won't be able to work correctly.

We can easily reorder these two structures because they are not in the hot path of anything (unlike frames and code objects).

Linked PRs

@pablogsal
Copy link
Member Author

I have requested to @Yhg1s to back port this to 3.12 and he agreed

pablogsal added a commit to pablogsal/cpython that referenced this issue Jun 27, 2023
pablogsal added a commit to pablogsal/cpython that referenced this issue Jun 27, 2023
pablogsal added a commit to pablogsal/cpython that referenced this issue Jun 27, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jun 27, 2023
…pection (pythonGH-106143)

(cherry picked from commit 2d5a1c2)

Co-authored-by: Pablo Galindo Salgado <[email protected]>
Signed-off-by: Pablo Galindo <[email protected]>
pablogsal added a commit to pablogsal/cpython that referenced this issue Jun 27, 2023
pablogsal added a commit to miss-islington/cpython that referenced this issue Jun 27, 2023
…pection (pythonGH-106143)

(cherry picked from commit 2d5a1c2)

Co-authored-by: Pablo Galindo Salgado <[email protected]>
Signed-off-by: Pablo Galindo <[email protected]>
pablogsal added a commit that referenced this issue Jun 27, 2023
…spection (GH-106143) (#106147)

gh-106140: Reorder some fields to facilitate out-of-process inspection (GH-106143)
(cherry picked from commit 2d5a1c2)

Signed-off-by: Pablo Galindo <[email protected]>
Co-authored-by: Pablo Galindo Salgado <[email protected]>
pablogsal added a commit to pablogsal/cpython that referenced this issue Jun 27, 2023
…-process inspection (pythonGH-106148)

(cherry picked from commit 9126a6a)

Co-authored-by: Pablo Galindo Salgado <[email protected]>
pablogsal added a commit to pablogsal/cpython that referenced this issue Jun 27, 2023
…-process inspection (pythonGH-106148)

(cherry picked from commit 9126a6a)

Co-authored-by: Pablo Galindo Salgado <[email protected]>
Signed-off-by: Pablo Galindo <[email protected]>
pablogsal added a commit that referenced this issue Jun 27, 2023
@markshannon
Copy link
Member

Did you benchmark these changes?
Moving the hot fields, specifically eval_breaker, deep into the interpreter state can have a negative performance impact.

This might benefit a few tool authors, but a slowdown hurts everyone.

@pablogsal
Copy link
Member Author

pablogsal commented Jul 28, 2023

Did you benchmark these changes?

Yes, I ran pyperformance in my local server with isolated CPUs and saw no measurable performance changes at all so this should be safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants