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

GDScript: Optimize operators by assuming the types #79990

Merged
merged 1 commit into from
Aug 1, 2023

Conversation

vnen
Copy link
Member

@vnen vnen commented Jul 28, 2023

This assumes that operators are called usually with the same type of operands as the first time. So it stores the types of the first run and if matched it uses an optimized path by calling the validated operator function directly. Otherwise it uses the regular untyped evaluator.

With this change, if operators do use the same type they run quite faster. OTOH, if the types mismatch it takes longer to run than they would with the previous code.

Note: this change may be a bit controversial as it makes operators slower when they fall in the non-optimized path (i.e. when the current operand types are different than the ones during the first run). The first time it ever runs is much slower, but since they are expected to run multiple times, this cost is amortized over time, as long as the optimized path is hit often.

I measured about 20% to 30% decrease in the execution time, when it falls into the optimized path. There's about 15% to 25% increase when it falls into the non-optimal path. All compared to the previous implementation of the operator opcode.

This doesn't affect validated operators (i.e. when types are known at compile time). The validated version is still faster.

This assumes that operators are called usually with the same type of
operands as the first time. So it stores the types of the first run and
if matched it uses an optimized path by calling the validated operator
function directly. Otherwise it uses the regular untyped evaluator.

With this change, if operators do use the same type they run quite
faster. OTOH, if the types mismatch it takes longer to run than they
would with the previous code.
@vnen vnen added this to the 4.2 milestone Jul 28, 2023
@vnen vnen requested a review from a team as a code owner July 28, 2023 16:25
Copy link
Member

@adamscott adamscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems right, even if I'm not used to the codegen part of the codebase.

This compounds, right? If you're doing things correctly, in a _process() loop (or in any loop), the optimization would be run each iteration, if I understand correctly.

And this makes me think that we should have a "trivia" or a "advanced notes" in the docs for GDScript for tidbits like that.

@reduz
Copy link
Member

reduz commented Jul 29, 2023

I think the rationale here is that in the vast majority of cases you are expected to use the same types always, so it should be a net win in general.

@reduz
Copy link
Member

reduz commented Jul 29, 2023

The assumed type optimizations can be implemented in a lot of places in the VM given now Godot has pointers to functions for almost everything.

Copy link
Contributor

@YuriSizov YuriSizov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving to signify that reduz seems to support this change.

@YuriSizov YuriSizov merged commit f6e02dc into godotengine:master Aug 1, 2023
@YuriSizov
Copy link
Contributor

Thanks!

@vnen vnen deleted the gdscript-assume-op-types branch October 19, 2023 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants