Skip to content

Conversation

@timholy
Copy link
Member

@timholy timholy commented Dec 8, 2021

This PR shaves about 100ms off the time to load packages with Revise running. (Testcase was Images.jl, which has lots of dependencies and also uses @require blocks.) The most important change is to eliminate constant-propagation for a number of methods that clearly shouldn't be specialized on particular constants. As identified in #38983, boolean keyword arguments are a particularly-frequent source of trouble. We may want to take a closer look at our heuristics, but in the meantime this seems reasonable to me.

This claws back much of the time lost due to timholy/Revise.jl#657.

These are targeted at reducing Revise latency if callbacks run
synchronously.
This shaves about 100ms off the time to load Images.jl
under Revise.
@aviatesk
Copy link
Member

aviatesk commented Dec 8, 2021

As identified in #38983, boolean keyword arguments are a particularly-frequent source of trouble

But the main purpose of constant prop' is to shape up the method body by eliminating unreachable blocks using constant information, which might then be successfully inlined into the caller context, and in this sense a boolean flag argument often leads to successful constant prop'.

But yes, we may be able to come up with better heuristics by inspecting those functions and figuring out the patterns that leads to unexpected recompilations.

@timholy
Copy link
Member Author

timholy commented Dec 8, 2021

Agreed that it serves a purpose, or this would have been a PR to disable const-prop for keyword arguments of body-functions. And I am not sure it's an easy problem to figure out which ones are useful and which ones are not. Yet it's amazing how often it crops up for this specific case.

@timholy
Copy link
Member Author

timholy commented Dec 8, 2021

In case people are skeptical, maybe it's helpful to share an example. Working with @quinnj, we identified const-prop as the reason for recompilation of https://github.com/JuliaData/CSV.jl/blob/1586ea1a57a168005420dafab9f3686c6cbd3ff5/src/file.jl#L224-L339. It's pretty insane that this method gets const-propped on chunking. The @nospecialize turns out to be a trick, prior to adding @constprop, to prevent it. Blocking const-prop in that case shaves seconds off latency, IIRC.

@chriselrod
Copy link
Contributor

Could File be split?
It's only the very end that uses chunking. Seems like it could define _file, defining the entire body except for those chunking checks at the end. Then File calls _file (which doesn't take chunking as an argument).

@timholy
Copy link
Member Author

timholy commented Dec 8, 2021

Agreed, but the main point is that the heuristic for deciding whether to const-prop is not very well-aligned with what a human would likely decide: as an example in this PR, should rehash! really be recompiled for different sizes of Dicts? That's a hard case to solve by splitting. Likewise, register_root_module only has one argument, so it can't be split, yet there's absolutely no point in recompiling it for specific modules. We're const-propping all sorts of stuff that we really don't need to be const-propping. I've only looked at a couple of packages with JuliaDebug/SnoopCompile.jl#272 but there's a heck of a lot of yellow. Undetermined as of yet is how much of this is justified. I'm sure much of it is, and I'm also sure much of it isn't.

While I've seen lots of examples that are just crazy, I haven't even begun to think about whether one could improve on the existing algorithm. I'm not even sure how much my own sense of the larger context (e.g., is this part of the function performance-sensitive? how is it typically called?) is coming into play here.

@timholy timholy merged commit 0064663 into master Dec 24, 2021
@timholy timholy deleted the teh/constprop_precompile branch December 24, 2021 08:23
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Feb 22, 2022
* Expand precompiles

These are targeted at reducing Revise latency if callbacks run
synchronously.

* Disable constprop on functions that don't benefit from it

This shaves about 100ms off the time to load Images.jl
under Revise.
LilithHafner pushed a commit to LilithHafner/julia that referenced this pull request Mar 8, 2022
* Expand precompiles

These are targeted at reducing Revise latency if callbacks run
synchronously.

* Disable constprop on functions that don't benefit from it

This shaves about 100ms off the time to load Images.jl
under Revise.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

latency Latency

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants