Skip to content

Commit 334ac14

Browse files
committed
Reduce overhead of maintaining 'warm' byte in executors.
1 parent a8d9d94 commit 334ac14

File tree

9 files changed

+13
-18
lines changed

9 files changed

+13
-18
lines changed

Include/internal/pycore_ceval.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ _PyEval_SpecialMethodCanSuggest(PyObject *self, int oparg);
332332
#define _PY_GC_SCHEDULED_BIT (1U << 4)
333333
#define _PY_EVAL_PLEASE_STOP_BIT (1U << 5)
334334
#define _PY_EVAL_EXPLICIT_MERGE_BIT (1U << 6)
335-
#define _PY_EVAL_JIT_INVALIDATE_COLD_BIT (1U << 7)
336335

337336
/* Reserve a few bits for future use */
338337
#define _PY_EVAL_EVENTS_BITS 8

Include/internal/pycore_interp_structs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ struct _is {
953953
struct _PyExecutorObject *executor_deletion_list_head;
954954
struct _PyExecutorObject *cold_executor;
955955
int executor_deletion_list_remaining_capacity;
956-
size_t trace_run_counter;
956+
int jited_ops_until_cleanup;
957957
_rare_events rare_events;
958958
PyDict_WatchCallback builtins_dict_watcher;
959959

Include/internal/pycore_optimizer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
115115
#endif
116116

117117
// Used as the threshold to trigger executor invalidation when
118-
// trace_run_counter is greater than this value.
119-
#define JIT_CLEANUP_THRESHOLD 100000
118+
// the number of uops jitted reaches this threshold
119+
#define JIT_CLEANUP_THRESHOLD 10000
120120

121121
// This is the length of the trace we project initially.
122122
#define UOP_MAX_TRACE_LENGTH 800
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Move cleanup of cold pieces of jitted code from the eval breaker to the jit
2+
compiler. This reduces the overhead of maintaining the "warm" bit.

Python/bytecodes.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5367,10 +5367,6 @@ dummy_func(
53675367

53685368
tier2 op(_MAKE_WARM, (--)) {
53695369
current_executor->vm_data.warm = true;
5370-
// It's okay if this ends up going negative.
5371-
if (--tstate->interp->trace_run_counter == 0) {
5372-
_Py_set_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT);
5373-
}
53745370
}
53755371

53765372
tier2 op(_FATAL_ERROR, (--)) {

Python/ceval_gil.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,12 +1395,6 @@ _Py_HandlePending(PyThreadState *tstate)
13951395
_Py_RunGC(tstate);
13961396
}
13971397

1398-
if ((breaker & _PY_EVAL_JIT_INVALIDATE_COLD_BIT) != 0) {
1399-
_Py_unset_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT);
1400-
_Py_Executors_InvalidateCold(tstate->interp);
1401-
tstate->interp->trace_run_counter = JIT_CLEANUP_THRESHOLD;
1402-
}
1403-
14041398
/* GIL drop request */
14051399
if ((breaker & _PY_GIL_DROP_REQUEST_BIT) != 0) {
14061400
/* Give another thread a chance */

Python/executor_cases.c.h

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ _PyOptimizer_Optimize(
152152
}
153153
(*executor_ptr)->vm_data.chain_depth = chain_depth;
154154
assert((*executor_ptr)->vm_data.valid);
155+
assert((*executor_ptr)->vm_data.warm);
156+
PyInterpreterState *interp = PyInterpreterState_Get();
157+
interp->jited_ops_until_cleanup -= (*executor_ptr)->code_size;
158+
if (interp->jited_ops_until_cleanup <= 0) {
159+
_Py_Executors_InvalidateCold(interp);
160+
interp->jited_ops_until_cleanup = JIT_CLEANUP_THRESHOLD;
161+
}
155162
return 1;
156163
}
157164

Python/pystate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ init_interpreter(PyInterpreterState *interp,
574574
interp->executor_list_head = NULL;
575575
interp->executor_deletion_list_head = NULL;
576576
interp->executor_deletion_list_remaining_capacity = 0;
577-
interp->trace_run_counter = JIT_CLEANUP_THRESHOLD;
577+
interp->jited_ops_until_cleanup = JIT_CLEANUP_THRESHOLD;
578578
if (interp != &runtime->_main_interpreter) {
579579
/* Fix the self-referential, statically initialized fields. */
580580
interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp);

0 commit comments

Comments
 (0)