-
-
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
Summary of non-ambiguous patterns of invalidation #35922
Comments
A good number of these are fixed in #35928 and various package PRs. |
Sounds like a good idea; I'll try it. |
I suspect that in combination with a slightly-enhanced #35877, if successful it would get rid of the large majority (80%? maybe even higher?) of the total invalidations for most packages I've tested. (Assuming that SnoopCompile is correctly categorizing ambiguity, which is not at all a given.) |
I gave that a quick try and so far it seems to make the compiler significantly slower. Apparently the extra type info is helpful. |
Bummer. I was so hopeful. Is there any useful profiling information about the source of the differential? I ask if it's specific because so much of the compiler is pretty well annotated with |
Maybe we could also introduce some function barriers manually? |
It's disturbing that StaticArrays features prominently here. I'm happy to take some concrete actions in the package if that can help things? |
Thanks for the offer! I think StaticArrays is mostly done, though, with a customized build (you need all my remaining latency-related PRs, here and in Pkg, plus #35877 including my tweak). That said, if you want to poke at this stuff, there should be pretty good docs available in SnoopCompile, and you'll get the hang of it very quickly. See brief extra note in #36018 (comment). |
Thanks! If there's a "proper fix" in the pipeline I'll leave off tweaking StaticArrays for now :-) |
Good plan. For the record, most invalidations from PkgA require a fix in Base, and most invalidations in PkgB require a fix in Base or PkgA. Only rarely have I found the right fix to be to delete or modify a method in the package that triggers the invalidation. And of course you see it only if you've already compiled or run the code in PkgA that gets invalidated by the methods defined in PkgB. So when I say that StaticArrays seems mostly done, I should clarify that (1) I mean the number of invalidations that it triggers in Base/Pkg/REPL is down by at least an order of magnitude if not more (there could still be a few that need fixing), and (2) I've not deliberately compiled a lot of the code in StaticArrays and seen whether it needs protection from invalidation by other packages. I don't expect that to be a big problem; I think most well-written packages probably won't need many changes, because most packages probably live in a world where inference works. A subset of packages are doomed to work with inherently non-inferrable objects, so those might require a round of attention at some point. (JuliaInterpreter and Revise are examples, but they have already gotten a fair bit of attention since they were loaded during my investigations.) |
This information is widely disseminated now and most of the specific instances in the table above have been addressed. |
I've looked at a enough cases, and developed enough tooling, to start getting a better sense for patterns. Here are some tests that load a few packages (just to get away from looking only at Base+stdlibs) and then load a new package (or execute a new command) while capturing invalidations.
reduce_empty(::Function, ::Type{T} where T)
init
argument tomaximum
so compiler knows what to do if container is empty.!
method!=(::Any, ::Any)
& similarconvert(::Type{T}, x::AbstractDict) where T<:AbstractDict
,cmp(::AbstractString, ::String)
ultimately from #15276, handlingExpr
args, ...unsafe_convert(::Type{Ptr{Nothing}}, b::Base.RefValue{T})
show_default
(primarilyshow(::IO, ::RawFD)
andshow_function
)cconvert(::Type{Ptr{Nothing}}, ::Any)
REPL.raw!
not knowing the handle isPtr{Cint}
(true?)to_indices(to_indices(A, I::Tuple)
all
,any
specializationsaxes(::AbstractArray)
CodeInfo.linetable
andCodeInfo.codelocs
(bothAny
)promote_rule(::Type{<:Any}, ::Type{<:Any}) = Bottom
+(::Int, ::Integer)
with no backedgesconvert(::Type{Array{C,N}}, ::Array{C,N} where {C<:Colorant,N}
Base._getindex(::IndexLinear, A::AbstractVector, i::Int)
to_index(::Integer)
OffsetInteger
typepromote_rule(::Type{Int64}, ::Type{T} where T)
promote_rule(::Type{<:Any}, ::Type{<:Any}) = Bottom
fallbackIf one discounts ambiguities, here's a summary:
struct
fields trigger problems; in many cases these have an obvious solution, but sometimes this conflicts with the merits of avoiding unnecessary specializationshow
methods)Takeaways for the compiler:
@nospecialize
annotations or where the compiler deliberately chooses not to specialize on an argument type, all calls with non-concrete types should be made by runtime dispatch? EDIT: thereduce_empty
case might even need more, if you're calling a method that hasn't been specialized, do it by runtime dispatch?Something I noticed and perhaps should mention: some MethodInstances appear to have no callers, e.g.,
I don't understand why this would be compiled if it doesn't have callers. Maybe they already got invalidated? There are quite a lot of these for
require_one_based_indexing
,to_indices
, and things like+(::Int, ::Integer)
.The text was updated successfully, but these errors were encountered: