-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
RFC: make boundscheck a value #22826
Conversation
doc/src/devdocs/ast.md
Outdated
Indicates the beginning or end of a section of code that performs a bounds check. Like `inbounds`, | ||
a stack is maintained, and the second argument can be one of: `true`, `false`, or `:pop`. | ||
Has the value `false` if inlined into a section of code marked with `@inbounds`, | ||
otherwise hase the value `true`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hase -> has
This seems like a really good idea (as evinced by code deletion :) ). That boundscheck meta elim code was a nightmare. |
base/essentials.jl
Outdated
end | ||
|
||
""" | ||
@inbounds(blk) | ||
|
||
Eliminates array bounds checking within expressions. | ||
|
||
In the example below the bound check of array A is skipped to improve performance. | ||
In the example below the in-range check for referencing | ||
element i of array A is skipped to improve performance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably code highlight i
and A
here
377fbac
to
87c8326
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unaddressed review above
should update devdocs. the meaning of different possible numbers of arguments here is worth documenting in comments and/or devdocs as it's not obvious |
87c8326
to
12dfdc9
Compare
addressed, though there's a test/staged failure across multiple platforms, and how the variable numbers of arguments thread through src is still a little confusing
7750694
to
9d0b926
Compare
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
9d0b926
to
d001ebb
Compare
hm, looks like some optimization passes weren't working right after some small changes to the AST. Let's try that again @nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
sufficient for removing dead code left over in typical boundscheck blocks in PR #22826
sufficient for removing dead code left over in typical boundscheck blocks in PR #22826
Sufficient for removing dead code left over in typical boundscheck blocks in PR #22826 Also reorders the meta-elimination-pass so that the later passes can be more effective
d001ebb
to
279eccb
Compare
Better, but still all jumbled up with the optimization change. Let's try again, now that that's on master: @nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
OK, I don't see anything now that doesn't appear to be noise. |
You don't think the 7 ~8x slowdowns in |
No. Locally, I don't see a difference between them. However, I see it does have a run-to-run variation of up to 50x. |
That's likely a variance introduced |
That variance number was computed on master |
Let's see a comparison run anyways @nanosoldier |
@@ -696,7 +697,7 @@ end | |||
|
|||
function push!(a::Array{Any,1}, @nospecialize item) | |||
_growend!(a, 1) | |||
arrayset(a, item, length(a)) | |||
arrayset(true, a, item, length(a)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what exactly arrayset(true, ...)
does, but isn't it safe to skip the bounds check here? The only case I can see is when _growend!()
would fail to grow an empty array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, grow can also fail due to finalizers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bound check doesn't really help catching that though....
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
That looks consistent to me. |
279eccb
to
ae9cc56
Compare
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
ae9cc56
to
273d4ac
Compare
@nanosoldier |
it is much easier if this value gets treated as a normal parameter as that allows all of the normal control flow logic to apply rather than require a complete reimplementation of it
273d4ac
to
d9dde5d
Compare
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
This optimization had been occurring before, but still isn't entirely valid
This PR turns the
@boundscheck
macro from being a special lexically scoped construct to being a normal value (Expr(:boundscheck)
returnstrue
, but can be replaced withfalse
by inference). This lets us treat it as a normal Bool parameter during control flow, rather than requiring special handling:I'm opening this to try to get a sense for whether this seems like an improvement or not. I noticed that as we moved to a more-linear IR, we need to bracket many more statements Expr(:inbounds), so this also should makes the IR a bit more concise.
This design fixes #18261 also, since we no longer need to keep track of the lexical boundscheck scope of the callee while inlining (something that we don't do very well at now), just the
inbounds
scope of the caller (which was easy to add).