The Wayback Machine - https://web.archive.org/web/20240216060455/https://github.com/python/cpython/pull/115181
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

gh-115178: Add Counts of UOp Sequences to pystats #115181

Open
wants to merge 35 commits into
base: main
Choose a base branch
from

Conversation

JeffersGlass
Copy link

@JeffersGlass JeffersGlass commented Feb 8, 2024

Adds the ability to track pairs, triples, and longer sequences of UOps to the pystats statistics.

Currently, this only counts these statistics for the non-JIT tier 2 interpreter. I intend to include tracking in the JIT in a follow-up PR.

To try it out, run:

./configure --enable-pystats
./make
mkdir /tmp/py_stats
PYTHON_UOPS=1 ./python -X pystats -c $'x = 0\nfor i in range(1000):\n x+=i'

The output file at /tmp/py_stats/???.txt will contain a new section with UOp Sequence counts:

UOp sequence count[BUILD_TUPLE,_CHECK_VALIDITY]: 2
UOp sequence count[LIST_APPEND,_CHECK_VALIDITY]: 13
UOp sequence count[LOAD_DEREF,_SET_IP]: 2
UOp sequence count[LOAD_FAST,LOAD_FAST]: 7
...

Tools/scripts/summarize_stats.py has also been expanded to encompass these new stats, with a new section:

Counts for top 100 UOp Sequences of Length 2
Sequence Count Self Cumulative
_CHECK_VALIDITY,_SET_IP 3,932 19.0% 19.0%
LOAD_NAME,_CHECK_VALIDITY 1,966 9.5% 28.6%
_SET_IP,LOAD_NAME 1,966 9.5% 38.1%
_ITER_CHECK_RANGE,_SET_IP 984 4.8% 42.9%
_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE 984 4.8% 47.6%
STORE_NAME,_SET_IP 983 4.8% 52.4%
STORE_NAME,_CHECK_VALIDITY 983 4.8% 57.1%
_SET_IP,STORE_NAME 983 4.8% 61.9%
_SET_IP,_BINARY_OP_ADD_INT 983 4.8% 66.7%
_SET_IP,_ITER_NEXT_RANGE 983 4.8% 71.4%
_SET_IP,_JUMP_TO_TOP 983 4.8% 76.2%
_GUARD_BOTH_INT,_CHECK_VALIDITY 983 4.8% 81.0%
_BINARY_OP_ADD_INT,_GUARD_BOTH_INT 983 4.8% 85.7%
_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE 983 4.8% 90.5%
_JUMP_TO_TOP,_CHECK_VALIDITY 983 4.8% 95.2%
_CHECK_VALIDITY,STORE_NAME 983 4.8% 100.0%

Finally, a new environment variable, PYTHONSTATS_UOPDEPTH can be set to any integer to record sequences of length longer than two. For example:

PYTHONSTATS_UOPDEPTH=4 PYTHON_UOPS=1 ./python -X pystats -c 'x = 0; for i in range(1000): x+=i

Yields:

Counts for top 100 UOp Sequences of Length 2
Sequence Count Self Cumulative
_CHECK_VALIDITY,_SET_IP 3,932 19.0% 19.0%
LOAD_NAME,_CHECK_VALIDITY 1,966 9.5% 28.6%
_SET_IP,LOAD_NAME 1,966 9.5% 38.1%
_ITER_CHECK_RANGE,_SET_IP 984 4.8% 42.9%
_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE 984 4.8% 47.6%
STORE_NAME,_SET_IP 983 4.8% 52.4%
STORE_NAME,_CHECK_VALIDITY 983 4.8% 57.1%
_SET_IP,STORE_NAME 983 4.8% 61.9%
_SET_IP,_BINARY_OP_ADD_INT 983 4.8% 66.7%
_SET_IP,_ITER_NEXT_RANGE 983 4.8% 71.4%
_SET_IP,_JUMP_TO_TOP 983 4.8% 76.2%
_GUARD_BOTH_INT,_CHECK_VALIDITY 983 4.8% 81.0%
_BINARY_OP_ADD_INT,_GUARD_BOTH_INT 983 4.8% 85.7%
_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE 983 4.8% 90.5%
_JUMP_TO_TOP,_CHECK_VALIDITY 983 4.8% 95.2%
_CHECK_VALIDITY,STORE_NAME 983 4.8% 100.0%
Counts for top 100 UOp Sequences of Length 3
Sequence Count Self Cumulative
LOAD_NAME,_CHECK_VALIDITY,_SET_IP 1,966 9.5% 9.5%
_SET_IP,LOAD_NAME,_CHECK_VALIDITY 1,966 9.5% 19.0%
_CHECK_VALIDITY,_SET_IP,LOAD_NAME 1,966 9.5% 28.6%
_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE,_SET_IP 984 4.8% 33.3%
STORE_NAME,_SET_IP,_BINARY_OP_ADD_INT 983 4.8% 38.1%
STORE_NAME,_CHECK_VALIDITY,_SET_IP 983 4.8% 42.9%
_SET_IP,STORE_NAME,_CHECK_VALIDITY 983 4.8% 47.6%
_SET_IP,_BINARY_OP_ADD_INT,_GUARD_BOTH_INT 983 4.8% 52.4%
_SET_IP,_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE 983 4.8% 57.1%
_SET_IP,_JUMP_TO_TOP,_CHECK_VALIDITY 983 4.8% 61.9%
_GUARD_BOTH_INT,_CHECK_VALIDITY,_SET_IP 983 4.8% 66.7%
_BINARY_OP_ADD_INT,_GUARD_BOTH_INT,_CHECK_VALIDITY 983 4.8% 71.4%
_ITER_CHECK_RANGE,_SET_IP,_JUMP_TO_TOP 983 4.8% 76.2%
_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE 983 4.8% 80.9%
_JUMP_TO_TOP,_CHECK_VALIDITY,STORE_NAME 983 4.8% 85.7%
_CHECK_VALIDITY,STORE_NAME,_SET_IP 983 4.8% 90.5%
_CHECK_VALIDITY,_SET_IP,STORE_NAME 983 4.8% 95.2%
_CHECK_VALIDITY,_SET_IP,_ITER_NEXT_RANGE 983 4.8% 100.0%
Counts for top 100 UOp Sequences of Length 4
Sequence Count Self Cumulative
_SET_IP,LOAD_NAME,_CHECK_VALIDITY,_SET_IP 1,966 9.5% 9.5%
_CHECK_VALIDITY,_SET_IP,LOAD_NAME,_CHECK_VALIDITY 1,966 9.5% 19.0%
LOAD_NAME,_CHECK_VALIDITY,_SET_IP,LOAD_NAME 983 4.8% 23.8%
LOAD_NAME,_CHECK_VALIDITY,_SET_IP,STORE_NAME 983 4.8% 28.6%
STORE_NAME,_SET_IP,_BINARY_OP_ADD_INT,_GUARD_BOTH_INT 983 4.8% 33.3%
STORE_NAME,_CHECK_VALIDITY,_SET_IP,_ITER_NEXT_RANGE 983 4.8% 38.1%
_SET_IP,STORE_NAME,_CHECK_VALIDITY,_SET_IP 983 4.8% 42.9%
_SET_IP,_BINARY_OP_ADD_INT,_GUARD_BOTH_INT,_CHECK_VALIDITY 983 4.8% 47.6%
_SET_IP,_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE 983 4.8% 52.4%
_SET_IP,_JUMP_TO_TOP,_CHECK_VALIDITY,STORE_NAME 983 4.8% 57.1%
_GUARD_BOTH_INT,_CHECK_VALIDITY,_SET_IP,LOAD_NAME 983 4.8% 61.9%
_BINARY_OP_ADD_INT,_GUARD_BOTH_INT,_CHECK_VALIDITY,_SET_IP 983 4.8% 66.7%
_ITER_CHECK_RANGE,_SET_IP,_JUMP_TO_TOP,_CHECK_VALIDITY 983 4.8% 71.4%
_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE,_SET_IP,_JUMP_TO_TOP 983 4.8% 76.2%
_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE,_ITER_CHECK_RANGE,_SET_IP 983 4.8% 80.9%
_JUMP_TO_TOP,_CHECK_VALIDITY,STORE_NAME,_SET_IP 983 4.8% 85.7%
_CHECK_VALIDITY,STORE_NAME,_SET_IP,_BINARY_OP_ADD_INT 983 4.8% 90.5%
_CHECK_VALIDITY,_SET_IP,STORE_NAME,_CHECK_VALIDITY 983 4.8% 95.2%
_CHECK_VALIDITY,_SET_IP,_ITER_NEXT_RANGE,_GUARD_NOT_EXHAUSTED_RANGE 983 4.8% 100.0%

EDIT: I see this has automatically requested a review from a huge number of people. This is my first time submitting a PR to CPython - please do forgive me if I've goofed this process up somehow.


📚 Documentation preview 📚: https://cpython-previews--115181.org.readthedocs.build/

Make optimization_stats.opcode an array of pointers to UOpStats objects,
instead of a member array.
Add a *next_stats[512] field to the UOpStats struct
Add _init_pystats function to initialize these new member structs
Call _init_pystats inside _PyConfig_Write
Add print_uop_sequence function to specialize.c to output stored
chains of uops
Sets the maximum depth of UOP sequences to track. Defaults to 2.
@JeffersGlass
Copy link
Author

Once again this seems to have automatically requested reviews from a bunch of Code Owners... not sure if that's due to the merge from Main or from touching pycore_code.h, but I do apologize.

@ericvsmith ericvsmith removed their request for review February 14, 2024 20:20
@Fidget-Spinner
Copy link
Member

Once again this seems to have automatically requested reviews from a bunch of Code Owners... not sure if that's due to the merge from Main or from touching pycore_code.h, but I do apologize.

I think your merge from main caught a bunch of unrelated changes (look at the diff of the PR in the files tab).

@erlend-aasland
Copy link
Contributor

Once again this seems to have automatically requested reviews from a bunch of Code Owners... not sure if that's due to the merge from Main or from touching pycore_code.h, but I do apologize.

This usually does the trick:

$ git switch <feature-branch>
$ # hack away
$ git commit
$ git switch main
$ git pull  # <= make sure main is up to date
$ git switch -
$ git merge --no-ff main -m "Sync with main"

@erlend-aasland
Copy link
Contributor

erlend-aasland commented Feb 14, 2024

@JeffersGlass, here's a recipe for fixing this:

$ git switch uop-sequence-count
$ git revert 03db7a5e950639cbbaea38ad4521f55ab39b1495
$ git switch main
$ git pull
$ git switch -
$ git merge --no-ff main

See also:

@JeffersGlass
Copy link
Author

Thank you both! @erlend-aasland your fix recipe worked a treat - I will be more careful about merging from main/pushing in the future.

Copy link
Member

@markshannon markshannon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor issues, but looks good in general.

Include/cpython/pystats.h Outdated Show resolved Hide resolved
Python/specialize.c Outdated Show resolved Hide resolved
Python/specialize.c Outdated Show resolved Hide resolved
@bedevere-app
Copy link

bedevere-app bot commented Feb 15, 2024

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@JeffersGlass
Copy link
Author

Thank you for the corrections. I have made the requested changes; please review again.

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

Successfully merging this pull request may close these issues.

None yet

7 participants