Skip to content

Conversation

@rafaqz
Copy link
Contributor

@rafaqz rafaqz commented Apr 21, 2022

BIGFLOATEXP1 and BIGEXP10 are inlined and constant propagated everywhere, and this has a large compilation overhead. Just removing all @inline on _scale methods gets the whole package precompilation down to 8 seconds!!

These benchmarks are using the reverted precompilation PR on main and this branch.

main:

julia> @time using Parsers
[ Info: Precompiling Parsers [69de0a69-1ddd-5017-9359-2bf0b02dc9f0]
 43.211173 seconds (728.55 k allocations: 65.818 MiB, 0.04% gc time, 1.71% compilation time)

This branch:

julia> @time using Parsers
[ Info: Precompiling Parsers [69de0a69-1ddd-5017-9359-2bf0b02dc9f0]
  8.454557 seconds (725.85 k allocations: 41.199 MiB, 0.25% gc time, 10.44% compilation time)

Should solve #113

@rafaqz rafaqz changed the title move large constants to a @noinline function dont @inline large constants Apr 21, 2022
@codecov
Copy link

codecov bot commented Apr 21, 2022

Codecov Report

Merging #114 (b407c88) into main (79fbfe6) will increase coverage by 0.04%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #114      +/-   ##
==========================================
+ Coverage   87.65%   87.70%   +0.04%     
==========================================
  Files           9        9              
  Lines        2309     2309              
==========================================
+ Hits         2024     2025       +1     
+ Misses        285      284       -1     
Impacted Files Coverage Δ
src/floats.jl 93.27% <100.00%> (+0.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 79fbfe6...b407c88. Read the comment docs.

@quinnj
Copy link
Member

quinnj commented Apr 21, 2022

Thanks; yeah, it's been on my priority list to circle back on precompilation. I think, like this PR, we just need to take things piece-by-piece and figure out the biggest wins while not regressing anything.

@quinnj quinnj merged commit 227ffa1 into JuliaData:main Apr 21, 2022
@rafaqz
Copy link
Contributor Author

rafaqz commented Apr 21, 2022

Yeah. I had some other pieces to add like a type stable Options which shaved 50%, but with this merged it does basically nothing. There are some real nonlinearities in compilation time.

@rafaqz rafaqz deleted the float_compilation branch April 21, 2022 15:37
@quinnj
Copy link
Member

quinnj commented Apr 21, 2022

What do you mean by type-stable Options? It isn't parameterized (anymore). Changing the types of some of hte fields?

@rafaqz
Copy link
Contributor Author

rafaqz commented Apr 21, 2022

A lot of the fields are Union. Inside those really large functions (and the functions that are inlined into them) the complexity of compiling that added up to doubling the precompilation time. But, only in the context that there was another major pressure on compilation - the large constant propagation. Without that it makes no real difference.

That's what I mean by non-linearities, sometimes type complexity has a large effect, sometimes none. I don't understand why. But it seems consistent from doing this a few times, that when you have high TTFX, replacing Union fields with fixed types in structs lowers TTFX a lot. But when TTFX is already lower it makes hardly any difference.

@charleskawczynski
Copy link

I don't understand why. But it seems consistent from doing this a few times, that when you have high TTFX, replacing Union fields with fixed types in structs lowers TTFX a lot. But when TTFX is already lower it makes hardly any difference.

Can you please elaborate on this?

@rafaqz
Copy link
Contributor Author

rafaqz commented Sep 6, 2024

I'm not sure of the cause. But initially removing unions gave a 30% or so improvement. Parsers.jl had massive compilation overhead from those inlined constants, and removing it fixed times a lot. But that meant removing the union no longer made much difference.

My theory is that there was some combinatorial effect of type instability and other workloads on the compiler when it's under pressure.

But that's just a gut feeling, I don't know what's actually happening internally.

@charleskawczynski
Copy link

Can you give a code example of what you mean by unions, though? E.g., in method signatures?

foo(::Union{A,B})

or union-splitting

if a isa A
elseif b isa B
end

or in types?

struct Foo{A <: Union{TA}}
end

@charleskawczynski
Copy link

charleskawczynski commented Sep 6, 2024

I've ran into an issue a while back with unions in the past that was catastrophic in terms of precompilation: CliMA/RRTMGP.jl#352.

@rafaqz
Copy link
Contributor Author

rafaqz commented Sep 7, 2024

I mean specifically Union field in structs and the type stability consequences. Unions in methods are just for dispatch, they don't effect types in the compiled methods.

@charleskawczynski
Copy link

Ah, yeah, we pretty consistently use concrete types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants