Skip to content

gh-109329: Count tier2 miss opcodes #110561

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

Merged
merged 4 commits into from
Oct 31, 2023

Conversation

mdboom
Copy link
Contributor

@mdboom mdboom commented Oct 9, 2023

This records the number of times a specific uop causes a DEOPT (in the same way this is already done for Tier 1). The summarize_stats.py script already supports the display, by virtue of reusing the code from Tier 1.

Marked as draft because it is necessarily built on #110398 which should be merged first.

@mdboom mdboom force-pushed the count-tier2-miss-opcodes branch from 22212fb to a08a127 Compare October 24, 2023 17:31
@mdboom mdboom marked this pull request as ready for review October 24, 2023 17:33
@markshannon
Copy link
Member

Looks like a useful feature. Do you have example output for this?

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

Mark put in a question, I can merge once you've answered that.

@@ -283,7 +283,7 @@ extern int _PyStaticCode_Init(PyCodeObject *co);
do { if (_Py_stats && PyFunction_Check(callable)) _Py_stats->call_stats.eval_calls[name]++; } while (0)
#define GC_STAT_ADD(gen, name, n) do { if (_Py_stats) _Py_stats->gc_stats[(gen)].name += (n); } while (0)
#define OPT_STAT_INC(name) do { if (_Py_stats) _Py_stats->optimization_stats.name++; } while (0)
#define UOP_EXE_INC(opname) do { if (_Py_stats) _Py_stats->optimization_stats.opcode[opname].execution_count++; } while (0)
#define UOP_STAT_INC(opname, name) do { if (_Py_stats) { assert(opname < 512); _Py_stats->optimization_stats.opcode[opname].name++; } } while (0)
Copy link
Member

Choose a reason for hiding this comment

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

I would have named this arg opcode (or OPCODE, per recent Discourse thread), since to me opname is a variable of type char * giving the opcode's name; opcode is the (named) constant representing the opcode, which it is. (I did a small double take when I saw assert(opname < 512). :-) But it's too late, and opname is used in several places above as well, so let's keep it this way.

@mdboom
Copy link
Contributor Author

mdboom commented Oct 30, 2023

Looks like a useful feature. Do you have example output for this?

Here's an example from the raytrace benchmark:

Name Count Self Cumulative Miss ratio
_SET_IP 487,881,600 22.3% 22.3%
_GUARD_TYPE_VERSION 184,373,760 8.4% 30.7% 2.2%
LOAD_FAST 153,382,980 7.0% 37.7%
_CHECK_MANAGED_OBJECT_HAS_VALUES 100,250,880 4.6% 42.3%
_LOAD_ATTR_INSTANCE_VALUE 100,250,880 4.6% 46.8%
_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 60,593,280 2.8% 49.6%
_GUARD_KEYS_VERSION 60,593,280 2.8% 52.4%
_LOAD_ATTR_METHOD_WITH_VALUES 60,593,280 2.8% 55.1%
RESUME_CHECK 60,407,040 2.8% 57.9%
_CHECK_PEP_523 60,407,040 2.8% 60.6%
_CHECK_FUNCTION_EXACT_ARGS 60,407,040 2.8% 63.4%
_CHECK_STACK_SPACE 60,407,040 2.8% 66.2%
_INIT_CALL_PY_EXACT_ARGS 60,407,040 2.8% 68.9%
_PUSH_FRAME 60,407,040 2.8% 71.7%
_SAVE_RETURN_OFFSET 60,407,040 2.8% 74.4%
_POP_FRAME 58,813,440 2.7% 77.1%
COMPARE_OP_INT 40,684,800 1.9% 79.0%
_POP_JUMP_IF_FALSE 40,308,480 1.8% 80.8%
_GUARD_GLOBALS_VERSION 40,120,320 1.8% 82.6%
_LOAD_GLOBAL_MODULE 40,120,320 1.8% 84.5%
_CHECK_ATTR_CLASS 39,548,160 1.8% 86.3%
_LOAD_ATTR_CLASS 39,548,160 1.8% 88.1%
_POP_JUMP_IF_TRUE 31,681,920 1.4% 89.5%
_ITER_CHECK_LIST 28,510,080 1.3% 90.8%
_IS_ITER_EXHAUSTED_LIST 28,510,080 1.3% 92.1%
STORE_FAST 27,071,940 1.2% 93.4%
_ITER_NEXT_LIST 25,484,160 1.2% 94.5%
POP_TOP 22,312,380 1.0% 95.5%
LOAD_CONST 21,757,440 1.0% 96.5%
_JUMP_TO_TOP 20,192,640 0.9% 97.5%
_GUARD_DORV_VALUES 19,459,200 0.9% 98.3%
_STORE_ATTR_INSTANCE_VALUE 19,459,200 0.9% 99.2%
_EXIT_TRACE 5,406,720 0.2% 99.5%
COMPARE_OP 1,758,720 0.1% 99.6%
LOAD_ATTR 1,543,680 0.1% 99.6%
CALL_METHOD_DESCRIPTOR_FAST 1,353,600 0.1% 99.7%
_ITER_CHECK_RANGE 1,036,800 0.0% 99.7%
_IS_ITER_EXHAUSTED_RANGE 1,036,800 0.0% 99.8%
_ITER_NEXT_RANGE 1,019,460 0.0% 99.8%
TO_BOOL_BOOL 768,000 0.0% 99.9%
_GUARD_BOTH_INT 752,640 0.0% 99.9%
BINARY_OP 382,080 0.0% 99.9%
BINARY_SUBSCR 376,320 0.0% 99.9%
_BINARY_OP_MULTIPLY_INT 376,320 0.0% 100.0%
_BINARY_OP_ADD_INT 376,320 0.0% 100.0%
GET_ITER 259,200 0.0% 100.0%
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS 190,080 0.0% 100.0%
_INIT_CALL_BOUND_METHOD_EXACT_ARGS 190,080 0.0% 100.0%
PUSH_NULL 1,860 0.0% 100.0%

@gvanrossum gvanrossum merged commit 84b4533 into python:main Oct 31, 2023
FullteaR pushed a commit to FullteaR/cpython that referenced this pull request Nov 3, 2023
This keeps a separate 'miss' counter for each micro-opcode, incremented whenever a guard uop takes a deoptimization side exit.
aisk pushed a commit to aisk/cpython that referenced this pull request Feb 11, 2024
This keeps a separate 'miss' counter for each micro-opcode, incremented whenever a guard uop takes a deoptimization side exit.
Glyphack pushed a commit to Glyphack/cpython that referenced this pull request Sep 2, 2024
This keeps a separate 'miss' counter for each micro-opcode, incremented whenever a guard uop takes a deoptimization side exit.
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.

3 participants