Skip to content

Use saturating counters for branch taken counters in _POP_JUMP_IF_FALSE and similar instructions. #151499

@markshannon

Description

@markshannon

Each conditional branch instruction contains a 16 bit field for recording the direction of the last 16 jumps.

    uint16_t *branches;
    uint16_t val = *branches;
    val = (val << 1) | direction;
    *branches =val;

This tells the direction of the last 16 branches.
When recording traces for the JIT, 16 branches is not a lot of information to guide region selection.

Instead, we could record the count of the two directions instead using a pair of saturating 8 bit counters.

    uint8_t branches[2];
    branches[direction] += (branches[direction] != 255);

Which is only one extra ALU instruction for most C compilers, and no extra memory accesses.

With a JIT warmup of up 500, we can get precise numbers of the branches taken.
With a warmup of a 1000, the saturating counters can still distinguish between branches that are rarely taken and those which are more balanced.

For example, if a branch switches direction every 20 times, the current counter might show a perfectly biased branch, but the saturating counter approach will show that the branch is roughly balanced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetopic-JIT
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions