-
Notifications
You must be signed in to change notification settings - Fork 49
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
Handle long tail of specialization for LOAD_ATTR
and CALL
with trampolines.
#447
Comments
Another use case for this is avoiding jumping in and out of the bytecode interpreter, e.g. def tuple(seq):
return LIST_TO_TUPLE( # Not an actual call, but the instruction
[ val for val in seq ] # No need for the extra scope, this can be inlined.
) One problem with schemes like this is that they prevent specialization, as all calls to |
Not to side-track from your focus in this issue, but how much of this could be mitigated with special-case eval loops (e.g. via our code generation tooling)? |
@markshannon: What's the status of this? Is this still targetted for 3.12? |
Probably not, but we might get some of this done for 3.12 |
python/cpython#107788 changes output of If we want to replace |
@markshannon Speaking of |
(And why does the |
Also, perhaps more pertinent to this issue, when the superblock projector gains the ability to project through a call (soon: gh-107793), will it need to trace through trampolines too? How will it find the bytecode for the trampoline? (I guess the trampoline needs to be an actual function object, not just a code object -- the design of my draft PR caches function objects indexed by |
Reviewing python/cpython#110317 got me thinking that we could handle this by defining the long tail specializations in terms of micro-ops, much as we do for common ones like Let's use
so there is plenty of unused space for an addition operand.
For tier2 we simply emit the micro-ops as we do now. We would need a special name to indicate that an inline cache entry was to be used as additional dispatching. E.g.
Maybe with an additional qualifier as well.
|
We are adding increasingly uncommon specializations of the
LOAD_ATTR
andCALL
instructions.Each of these specializations increases our hit-rate, improving the potential for tier-2 optimizations, but often has a negligible or even negative impact on tier-1 (PEP 659) performance as the increasing size of the interpreter makes for more icache misses.
Instead of adding more and more specialization we can add trampoline functions (in bytecode, but not full Python functions) to perform some of the work that would be done in a specialized instructions.
These trampolines are unlikely to boost tier-1 performance, in fact they may make it a bit worse, but they allow much more open ended specializations, and expose the details of the specializations to higher tier optimizers in a way that they can understand without needing custom code for each specialization.
This idea isn't limited to
CALL
andLOAD_ATTR
, but those have the most complex and varied semantics.Examples:
Calling a Python function with complex arguments or parameters.
When specializing a call, we know both the shape of the arguments and the parameters, allowing us to compute (or lookup for the most common cases) a sequence of operations to move the arguments to the right place in the locals. Having individual specializations for each of these cases would be silly. We could have a custom format describing the transformation packed into the cache, but to do that would need a custom mini-interpreter.
Better to create a trampoline function that does the argument shuffle and then tailcalls into the function.
Calling a Python class.
GH-91095: Specialize calls to normal python classes python/cpython#93221 specializes calling Python classes using a custom specialized instruction and a stub function to clean up after the call. This could be replaced with a more general trampoline specialized instruction. Doing so would allow trampolines to handle differing shapes of arguments, without a proliferation of instructions.
The text was updated successfully, but these errors were encountered: