Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove eval_breaker and kwnames local variables from interpreter definition. #104580

Closed
markshannon opened this issue May 17, 2023 · 1 comment
Closed
Assignees
Labels
performance Performance or resource usage

Comments

@markshannon
Copy link
Member

markshannon commented May 17, 2023

Currently there are quite a few local variables in PyEval_EvalDefault().
Each of these is:

  • A candidate for register allocation, confusing the compiler.
  • Potentially adds extra state to the interpreter
  • Adds complexity to automatically generated interpreters and compilers

The local variables break down into three classes:

  • The state of the interpreter
  • Transient values
  • Values for gathering stats, debugging, etc.

The last category are not present in release builds, so we can ignore those.
The transient values, like opcode and oparg are an artifact of the dispatching mechanism and will be absent for compiled code, or different for a different interpreter.

It is the remaining values that matter.
Each of these will consume a register in compiled code, and need to kept in sync where there is redundancy.
The current values are:

  • next_instr -- The VM instruction pointer
  • frame -- Pointer to the current frame
  • stackpointer -- Pointer to the top of stack
  • tstate -- Pointer to the current thread
  • eval_break -- Pointer to the eval-breaker
  • kwnames -- Pointer to the keyword names, if any for the next call

next_instr and frame are fundamental to VM operation.

Hypothetically stackpointer can be eliminated by a compiler, and tstate can be eliminated by some clever stack arrangement, or using thread-local storage. However, these approaches are complex and may not be worthwhile.

eval_breaker can easily be eliminated, as it is redundant. eval_breaker == tstate->interp->eval_breaker

kwnames is logically transient, in that it is only valid between the KW_NAMES instruction and a CALL. However from the very local view of a single instruction it is effectively an interpreter-wide value.
It can removed by pushing the kwnames to the stack, but that is likely to cause a slowdown. We need to experiment.

Linked PRs

@markshannon markshannon added the performance Performance or resource usage label May 17, 2023
markshannon added a commit that referenced this issue May 18, 2023
Move eval-breaker to the front of the interpreter state.
carljm added a commit to carljm/cpython that referenced this issue May 18, 2023
* main:
  pythongh-74690: Don't set special protocol attributes on non-protocol subclasses of protocols (python#104622)
  pythongh-104623: Update Windows installer to use SQLite 3.42.0 (python#104625)
  pythongh-104050: Add more type annotations to Argument Clinic (python#104628)
  pythongh-104629: Don't skip test_clinic if _testclinic is missing (python#104630)
  pythongh-104549: Set __module__ on TypeAliasType (python#104550)
  pythongh-104050: Improve some typing around `default`s and sentinel values (python#104626)
  pythongh-104146: Remove unused vars from Argument Clinic (python#104627)
  pythongh-104615: don't make unsafe swaps in apply_static_swaps (python#104620)
  pythonGH-104484: Add case_sensitive argument to `pathlib.PurePath.match()` (pythonGH-104565)
  pythonGH-96803: Document and test new unstable internal frame API functions (pythonGH-104211)
  pythonGH-104580: Don't cache eval breaker in interpreter (pythonGH-104581)
@markshannon
Copy link
Member Author

Fixed by #109300

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Performance or resource usage
Projects
None yet
Development

No branches or pull requests

2 participants