summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2024-02-22 20:23:48 (GMT)
committerGitHub <noreply@github.com>2024-02-22 20:23:48 (GMT)
commit4ee6bdfbaa792a3aa93c65c2022a89bd2d1e0894 (patch)
tree7ad7e56f85ec15887338b86e292670fd60abc9db /Python
parent1002fbe12e0bd8c9a54bc5addbf5d94a5b35f91f (diff)
downloadcpython-4ee6bdfbaa792a3aa93c65c2022a89bd2d1e0894.zip
cpython-4ee6bdfbaa792a3aa93c65c2022a89bd2d1e0894.tar.gz
cpython-4ee6bdfbaa792a3aa93c65c2022a89bd2d1e0894.tar.bz2
gh-115727: Reduce confidence even on 100% predicted jumps (#115748)
The theory is that even if we saw a jump go in the same direction the last 16 times we got there, we shouldn't be overly confident that it's still going to go the same way in the future. This PR makes it so that in the extreme cases, the confidence is multiplied by 0.9 instead of remaining unchanged. For unpredictable jumps, there is no difference (still 0.5). For somewhat predictable jumps, we interpolate.
Diffstat (limited to 'Python')
-rw-r--r--Python/optimizer.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 74708be..6b2ba3a 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -546,6 +546,8 @@ top: // Jump here after _PUSH_FRAME or likely branches
uint32_t oparg = instr->op.arg;
uint32_t extended = 0;
+ DPRINTF(3, "%d: %s(%d)\n", target, _PyOpcode_OpName[opcode], oparg);
+
if (opcode == ENTER_EXECUTOR) {
assert(oparg < 256);
_PyExecutorObject *executor = code->co_executors->executors[oparg];
@@ -593,21 +595,25 @@ top: // Jump here after _PUSH_FRAME or likely branches
int counter = instr[1].cache;
int bitcount = _Py_popcount32(counter);
int jump_likely = bitcount > 8;
+ /* If bitcount is 8 (half the jumps were taken), adjust confidence by 50%.
+ If it's 16 or 0 (all or none were taken), adjust by 10%
+ (since the future is still somewhat uncertain).
+ For values in between, adjust proportionally. */
if (jump_likely) {
- confidence = confidence * bitcount / 16;
+ confidence = confidence * (bitcount + 2) / 20;
}
else {
- confidence = confidence * (16 - bitcount) / 16;
+ confidence = confidence * (18 - bitcount) / 20;
}
+ uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely];
+ DPRINTF(2, "%d: %s(%d): counter=%x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n",
+ target, _PyOpcode_OpName[opcode], oparg,
+ counter, bitcount, jump_likely, confidence, _PyUOpName(uopcode));
if (confidence < CONFIDENCE_CUTOFF) {
- DPRINTF(2, "Confidence too low (%d)\n", confidence);
+ DPRINTF(2, "Confidence too low (%d < %d)\n", confidence, CONFIDENCE_CUTOFF);
OPT_STAT_INC(low_confidence);
goto done;
}
- uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely];
- DPRINTF(2, "%s(%d): counter=%x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n",
- _PyOpcode_OpName[opcode], oparg,
- counter, bitcount, jump_likely, confidence, _PyUOpName(uopcode));
_Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]];
_Py_CODEUNIT *target_instr = next_instr + oparg;
if (jump_likely) {