Skip to content

Split micro-ops that have different behavior depending on low bit of oparg.  #115457

Closed

Description

@markshannon

Splitting these micro-ops will improve performance by reducing the number of branches, the size of code generated, and the number of holes in the JIT stencils. There is no real downside; the increase in complexity at runtime is negligible and there isn't much increased complexity in the tooling.

Taking _LOAD_ATTR_INSTANCE_VALUE as an example, as it is the dynamically most common.

    op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, owner -- attr, null if (oparg & 1))) {
        ...

can be split into

    op(_LOAD_ATTR_INSTANCE_VALUE_0, (index/1, owner -- attr)) {
        assert((oparg & 1) == 0);
        ...

and

    op(_LOAD_ATTR_INSTANCE_VALUE_1, (index/1, owner -- attr, null)) {
        assert((oparg & 1) == 1);
        ...

Each of these is simpler, thus smaller and faster than the base version.
We can always choose one of the two split version when projecting the trace, so we don't need an implementation of the base version at all. This means that the tier 2 interpreter and stencils aren't much bigger than before.

Linked PRs

Activity

  1. self-assigned this
    on Feb 15, 2024
  2. markshannon commented on Feb 16, 2024

    @markshannon
    MemberAuthor

    It makes sense to do replication at the same time as splitting.

    By replication, I mean creating a copy of the replicated uop for each oparg in a given set.
    This is not such an obvious win, as we need multiple stencils, but each stencil can be significantly smaller than the original.

    The best example is _INIT_CALL_PY_EXACT_ARGS which has a stencil of 753 bytes, whereas the stencil for _INIT_CALL_PY_EXACT_ARGS_0 is only 308 bytes, a ~60% saving.

    _LOAD_FAST shows a smaller saving, from 45 bytes down to 31 for LOAD_FAST_0.

  3. added a commit that references this issue on Feb 20, 2024
  4. added a commit that references this issue on Mar 4, 2024
  5. added a commit that references this issue on Apr 17, 2024
  6. added a commit that references this issue on Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usage

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions