-
Notifications
You must be signed in to change notification settings - Fork 93
Add nospecialize to some very highly specialized methods #2830
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
base: master
Are you sure you want to change the base?
Conversation
These cut 100k method instances. Still need to benchmark properly.
|
::Type{S}, | ||
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet} | ||
@nospecialize(model::AbstractModel), | ||
@nospecialize(F::Type{<:MOI.AbstractFunction}), |
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.
This one may be more dangerous
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.
Note that the inner method will be compiled. It's just this one that isn't.
With lots of bridgesSlower because GC runs. Beforejulia> using JuMP, Gurobi, BenchmarkTools
julia> const ENV = Gurobi.Env()
Set parameter WLSAccessID
Set parameter WLSSecret
Set parameter LicenseID to value 722777
WLS license 722777 - registered to JuMP Development
Gurobi.Env(Ptr{Nothing} @0x000000012a809400, false, 0)
julia> function main(n)
model = Model(() -> Gurobi.Optimizer(ENV))
set_silent(model)
@variable(model, x[1:n])
@constraint(model, c[i in 1:n], 0 <= i * x[i] <= i)
MOI.Utilities.attach_optimizer(model)
return model
end
main (generic function with 1 method)
julia> @benchmark(main(100_000); setup = GC.gc())
BenchmarkTools.Trial: 16 samples with 1 evaluation per sample.
Range (min … max): 174.960 ms … 216.162 ms ┊ GC (min … max): 0.00% … 18.86%
Time (median): 176.379 ms ┊ GC (median): 0.00%
Time (mean ± σ): 180.940 ms ± 12.739 ms ┊ GC (mean ± σ): 2.60% ± 6.04%
██
▄██▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▄▁▁▁▁▁▁▁▄ ▁
175 ms Histogram: frequency by time 216 ms <
Memory estimate: 344.67 MiB, allocs estimate: 6303323. Afterjulia> using JuMP, Gurobi, BenchmarkTools
julia> const ENV = Gurobi.Env()
Set parameter WLSAccessID
Set parameter WLSSecret
Set parameter LicenseID to value 722777
WLS license 722777 - registered to JuMP Development
Gurobi.Env(Ptr{Nothing} @0x0000000127ddd000, false, 0)
julia> function main(n)
model = Model(() -> Gurobi.Optimizer(ENV))
set_silent(model)
@variable(model, x[1:n])
@constraint(model, c[i in 1:n], 0 <= i * x[i] <= i)
MOI.Utilities.attach_optimizer(model)
return model
end
main (generic function with 1 method)
julia> @benchmark(main(100_000); setup = GC.gc())
BenchmarkTools.Trial: 14 samples with 1 evaluation per sample.
Range (min … max): 213.427 ms … 235.628 ms ┊ GC (min … max): 14.28% … 19.73%
Time (median): 229.635 ms ┊ GC (median): 19.44%
Time (mean ± σ): 228.419 ms ± 5.341 ms ┊ GC (mean ± σ): 18.89% ± 1.57%
▁ ▁ █▁ █ █ ██ ▁
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██▁█▁▁▁█▁██▁▁▁▁▁▁▁▁▁▁█ ▁
213 ms Histogram: frequency by time 236 ms <
Memory estimate: 349.26 MiB, allocs estimate: 6503956. Without bridgesNo change. Beforejulia> function main2(n)
model = Model(() -> Gurobi.Optimizer(ENV))
set_silent(model)
@variable(model, x[1:n])
@constraint(model, c[i in 1:n], i * x[i] >= i)
MOI.Utilities.attach_optimizer(model)
return model
end
main2 (generic function with 1 method)
julia> @benchmark(main2(100_000); setup = GC.gc())
BenchmarkTools.Trial: 20 samples with 1 evaluation per sample.
Range (min … max): 117.079 ms … 120.962 ms ┊ GC (min … max): 0.00% … 0.00%
Time (median): 119.386 ms ┊ GC (median): 0.00%
Time (mean ± σ): 119.362 ms ± 868.501 μs ┊ GC (mean ± σ): 0.00% ± 0.00%
▁ ▁ █▁ ▁▁█ ▁ █ ▁▁ ▁▁ ▁ ▁ ▁ ▁
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁██▁▁▁▁███▁▁█▁█▁▁██▁██▁▁▁█▁█▁▁▁▁█▁▁▁▁█ ▁
117 ms Histogram: frequency by time 121 ms <
Memory estimate: 263.94 MiB, allocs estimate: 4802694. Afterjulia> function main2(n)
model = Model(() -> Gurobi.Optimizer(ENV))
set_silent(model)
@variable(model, x[1:n])
@constraint(model, c[i in 1:n], i * x[i] >= i)
MOI.Utilities.attach_optimizer(model)
return model
end
main2 (generic function with 1 method)
julia> @benchmark(main2(100_000); setup = GC.gc())
BenchmarkTools.Trial: 20 samples with 1 evaluation per sample.
Range (min … max): 117.935 ms … 124.710 ms ┊ GC (min … max): 0.00% … 0.00%
Time (median): 121.387 ms ┊ GC (median): 0.00%
Time (mean ± σ): 121.877 ms ± 1.833 ms ┊ GC (mean ± σ): 0.00% ± 0.00%
▃ ▃ █ ▃
▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇▁▁▁▁▁▇█▁▁█▁▁█▁▁▇▇▁▇▁▁▁▁▁▁▁▁▇▁▁▁▁▁▇▁▇▇▁▁▁▁▁▇█ ▁
118 ms Histogram: frequency by time 125 ms <
Memory estimate: 263.94 MiB, allocs estimate: 4802694. |
There doesn't seem to be any difference in the test runtime of So maybe they're such tiny methods that it doesn't really matter. |
I guess I should try: https://timholy.github.io/SnoopCompile.jl/dev/tutorials/pgdsgui/. I remember looking at it a couple of years ago without much obvious success. |
Even without bridges this is much better. Beforejulia> using JuMP, Gurobi
julia> const ENV = Gurobi.Env()
Set parameter WLSAccessID
Set parameter WLSSecret
Set parameter LicenseID to value 722777
WLS license 722777 - registered to JuMP Development
Gurobi.Env(Ptr{Nothing} @0x0000000142a8ac00, false, 0)
julia> function main2(n)
model = Model(() -> Gurobi.Optimizer(ENV))
set_silent(model)
@variable(model, x[1:n])
@constraint(model, c[i in 1:n], i * x[i] >= i)
MOI.Utilities.attach_optimizer(model)
return model
end
main2 (generic function with 1 method)
julia> @time main2(100_000)
0.338462 seconds (4.99 M allocations: 273.114 MiB, 26.99% gc time, 38.53% compilation time)
A JuMP Model
├ solver: Gurobi
├ objective_sense: FEASIBILITY_SENSE
├ num_variables: 100000
├ num_constraints: 100000
│ └ AffExpr in MOI.GreaterThan{Float64}: 100000
└ Names registered in the model
└ :c, :x Afterjulia> using JuMP, Gurobi
julia> const ENV = Gurobi.Env()
Set parameter WLSAccessID
Set parameter WLSSecret
Set parameter LicenseID to value 722777
WLS license 722777 - registered to JuMP Development
Gurobi.Env(Ptr{Nothing} @0x0000000118251000, false, 0)
julia> function main2(n)
model = Model(() -> Gurobi.Optimizer(ENV))
set_silent(model)
@variable(model, x[1:n])
@constraint(model, c[i in 1:n], i * x[i] >= i)
MOI.Utilities.attach_optimizer(model)
return model
end
main2 (generic function with 1 method)
julia> @time main2(100_000)
0.228506 seconds (4.84 M allocations: 265.752 MiB, 42.85% gc time, 6.42% compilation time)
A JuMP Model
├ solver: Gurobi
├ objective_sense: FEASIBILITY_SENSE
├ num_variables: 100000
├ num_constraints: 100000
│ └ AffExpr in MOI.GreaterThan{Float64}: 100000
└ Names registered in the model
└ :c, :x |
Thoughts @blegat? |
x-ref #2829