gh-138050: [WIP] JIT - Streamline MAKE_WARM - move coldness check to executor creation (GH-138240)

This commit is contained in:
alm 2025-10-27 18:37:37 +02:00 committed by GitHub
parent e03d8e4f50
commit 1753ccb432
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 15 additions and 13 deletions

View file

@ -939,7 +939,7 @@ struct _is {
struct _PyExecutorObject *executor_deletion_list_head; struct _PyExecutorObject *executor_deletion_list_head;
struct _PyExecutorObject *cold_executor; struct _PyExecutorObject *cold_executor;
int executor_deletion_list_remaining_capacity; int executor_deletion_list_remaining_capacity;
size_t trace_run_counter; size_t executor_creation_counter;
_rare_events rare_events; _rare_events rare_events;
PyDict_WatchCallback builtins_dict_watcher; PyDict_WatchCallback builtins_dict_watcher;

View file

@ -90,8 +90,9 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
#endif #endif
// Used as the threshold to trigger executor invalidation when // Used as the threshold to trigger executor invalidation when
// trace_run_counter is greater than this value. // executor_creation_counter is greater than this value.
#define JIT_CLEANUP_THRESHOLD 100000 // This value is arbitrary and was not optimized.
#define JIT_CLEANUP_THRESHOLD 1000
#define TRACE_STACK_SIZE 5 #define TRACE_STACK_SIZE 5

View file

@ -11,7 +11,6 @@
#include "pycore_audit.h" // _PySys_Audit() #include "pycore_audit.h" // _PySys_Audit()
#include "pycore_backoff.h" #include "pycore_backoff.h"
#include "pycore_cell.h" // PyCell_GetRef() #include "pycore_cell.h" // PyCell_GetRef()
#include "pycore_ceval.h"
#include "pycore_code.h" #include "pycore_code.h"
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
#include "pycore_function.h" #include "pycore_function.h"
@ -5362,10 +5361,6 @@ dummy_func(
tier2 op(_MAKE_WARM, (--)) { tier2 op(_MAKE_WARM, (--)) {
current_executor->vm_data.warm = true; current_executor->vm_data.warm = true;
// It's okay if this ends up going negative.
if (--tstate->interp->trace_run_counter == 0) {
_Py_set_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT);
}
} }
tier2 op(_FATAL_ERROR, (--)) { tier2 op(_FATAL_ERROR, (--)) {

View file

@ -1398,7 +1398,7 @@ _Py_HandlePending(PyThreadState *tstate)
if ((breaker & _PY_EVAL_JIT_INVALIDATE_COLD_BIT) != 0) { if ((breaker & _PY_EVAL_JIT_INVALIDATE_COLD_BIT) != 0) {
_Py_unset_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT); _Py_unset_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT);
_Py_Executors_InvalidateCold(tstate->interp); _Py_Executors_InvalidateCold(tstate->interp);
tstate->interp->trace_run_counter = JIT_CLEANUP_THRESHOLD; tstate->interp->executor_creation_counter = JIT_CLEANUP_THRESHOLD;
} }
/* GIL drop request */ /* GIL drop request */

View file

@ -7409,9 +7409,6 @@
case _MAKE_WARM: { case _MAKE_WARM: {
current_executor->vm_data.warm = true; current_executor->vm_data.warm = true;
if (--tstate->interp->trace_run_counter == 0) {
_Py_set_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT);
}
break; break;
} }

View file

@ -6,6 +6,7 @@
#include "pycore_interp.h" #include "pycore_interp.h"
#include "pycore_backoff.h" #include "pycore_backoff.h"
#include "pycore_bitutils.h" // _Py_popcount32() #include "pycore_bitutils.h" // _Py_popcount32()
#include "pycore_ceval.h" // _Py_set_eval_breaker_bit
#include "pycore_code.h" // _Py_GetBaseCodeUnit #include "pycore_code.h" // _Py_GetBaseCodeUnit
#include "pycore_function.h" // _PyFunction_LookupByVersion() #include "pycore_function.h" // _PyFunction_LookupByVersion()
#include "pycore_interpframe.h" #include "pycore_interpframe.h"
@ -1343,6 +1344,14 @@ uop_optimize(
return -1; return -1;
} }
assert(length <= UOP_MAX_TRACE_LENGTH); assert(length <= UOP_MAX_TRACE_LENGTH);
// Check executor coldness
PyThreadState *tstate = PyThreadState_Get();
// It's okay if this ends up going negative.
if (--tstate->interp->executor_creation_counter == 0) {
_Py_set_eval_breaker_bit(tstate, _PY_EVAL_JIT_INVALIDATE_COLD_BIT);
}
*exec_ptr = executor; *exec_ptr = executor;
return 1; return 1;
} }

View file

@ -571,7 +571,7 @@ init_interpreter(PyInterpreterState *interp,
interp->executor_list_head = NULL; interp->executor_list_head = NULL;
interp->executor_deletion_list_head = NULL; interp->executor_deletion_list_head = NULL;
interp->executor_deletion_list_remaining_capacity = 0; interp->executor_deletion_list_remaining_capacity = 0;
interp->trace_run_counter = JIT_CLEANUP_THRESHOLD; interp->executor_creation_counter = JIT_CLEANUP_THRESHOLD;
if (interp != &runtime->_main_interpreter) { if (interp != &runtime->_main_interpreter) {
/* Fix the self-referential, statically initialized fields. */ /* Fix the self-referential, statically initialized fields. */
interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp); interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp);