-
-
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
TupleMap type #15779
TupleMap type #15779
Conversation
79b0e2f
to
ee1a1ea
Compare
# toplevel lambda - infer directly | ||
frame = InferenceState(linfo, linfo.specTypes, svec(), true) | ||
typeinf_loop(frame) | ||
@assert frame.inferred # TODO: deal with the better |
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.
deal with the what?
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. as in the assert that used to be elsewhere, but now is in a place that it can be dealt with
There are a number of unrelated commits in here. Can we please get those as a separate pull request? This is enough of a monster to review as is. |
only the first two codegen changes are unrelated (they are passing CI, so maybe i should just push those to master now?) the last two are pre-existing, but conflict significantly with the other changes, so I can't pull them out (although I could commit the equivalent fix to master and then revert them in this PR) |
Yes, pulling out even 2 commits to master is helpful. |
e6adb2b also looks separate |
it could be squashed into ac48b6b, but it's a PR fix, not a bugfix |
ok, updated to remove those three commits |
// the most specific for the argument types. | ||
union jl_typemap_t invokes; | ||
|
||
int32_t called; // bit flags: whether each of the first 8 arguments is called |
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.
Is it still 8 arguments or is it 32 now?
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.
still 8, but now stored in an Int32 type (because that's what's available to jltypes.c during initialization)
0b2ddef
to
c1fa1eb
Compare
this abstracts out the method lookup behavior of the MethodTable cache with the goal of making it more re-usable for the tfunc lookup (speed) and helping address #265 (correctness)
jl_array_t *arg1; // Array{union jl_typemap_t} | ||
jl_array_t *targ; // Array{union jl_typemap_t} | ||
jl_typemap_entry_t *linear; // union jl_typemap_t (but no more levels) | ||
jl_value_t *key; // [nullable] |
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.
What does nullable mean here? C NULL?
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.
yes (taking inspiration from Glib, which uses this notation in its documentation)
I think it would help a lot to move the code for typemap to a separate file, since a major point of this change is to factor out the data structure from its clients. |
I get the sense that using the same structure for method definitions and method/tfunc caches is a big source of complexity here. Passing boolean flags to the table to tell it how to operate is kind of a warning sign to me. An API cleanup might be in order. For example There are some un-renamed instances of |
jl_lambda_info_t *method, jl_svec_t *tvars, | ||
int8_t isstaged); | ||
int jl_is_type(jl_value_t *v); | ||
void jl_method_table_insert(jl_methtable_t *mt, jl_tupletype_t *type, jl_tupletype_t *simpletype, |
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.
What does the simpletype
argument to this mean? It also seems to be more of an implementation detail that doesn't really belong in this entry point.
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.
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.
Both of those bugs were closed without changing this API. Intuitively, to add a method you need a method table, a method, and possibly a separate type argument. Therefore that's what the arguments should be.
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.
true, they were closed but not fixed. i'll add my test for the remaining case.
Is this PR the cause of #15893? |
Yes, it certainly seems to be. |
local tfunc_idx = -1 | ||
local frame | ||
local frame = nothing | ||
offs = 0 |
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.
What is this for?
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.
compatibility with the existing API inherited from the previous implementation of MethodTable->cache_targs / cache_args1
. I would like to drop offs
entirely (I have a commit to do it because it enables another optimization, but it only seemed to save ~0.5% on yichao's dispatch perf test), but in the existing codebase, it is used to decide whether the cache should split on the first or second argument type.
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.
Ok, but since inference only ever passes 0
it doesn't seem to need to be part of jl_tfunc_cache_insert
and jl_tfunc_cache_lookup
.
I do see some nice speedups on some of the tests, such as subarray and linalg/triangular. That's really good, but now I'm getting greedy and want to understand better where the speedup comes from. There are a few candidates:
If we can separate these effects I see potential either for further speedups or simplifying the code or both. |
CI instability is going to waste more time than faster tests, so if that can't be fixed soon then I think it would be appropriate to revert this for now until it can be done in a stable and properly reviewed way. And while we're renaming things, what about |
the flags in for the other flags, it's tricky since the structure of dispatch is such that it is one data-structure, but there are a number of related questions that we are interested in asking them (intersection, more-specific, typeseq, subtype, and iteration). the bool flags attempt to balance between providing too generic entry points (like |
this is the entry point for creating a |
agreed. this would involve splitting the file at around line ~1150 and making the the relevant header entries exist. the only part that's made me hesitate is wondering whether gcc is doing any sort of IPO that would be inhibited by the split. |
That's not the kind of performance I want :P |
that depends on which benchmark you want to optimize :P faster faster faster dispatch? i think we could play more games here to unroll common cases and copy more data inline to avoid a pointer indirection more compact cache levels? there's a limiting case where the user generates something foolish like |
Ah yeah PkgEval would have also been a good idea on a change this big that's supposed to not be user visible. |
@andreasnoack fixed by #15904 |
@vtjnash still need to fix
|
The purpose of this change set is to separate the method caching logic used by generic functions into a independent utility. The motivation for this changes was #265 and (more recently, but related) #15555. Since both require the compiler to be able to invalidate various method caches, it seemed most practical to me to have this functionality available independent of generic function dispatch (so that dispatch is a consumer of this logic and information instead of the provider).
For reviewing, I recommend starting from the definition of the new TypeMap type (as in, a map from a type to a value, allowing use of either
==
or<:
) in julia.h (https://github.com/JuliaLang/julia/compare/jn/methcache?expand=1#diff-67021262df1246d0b5756f73b92eb69fR167)this may have unintentionally provided a easy fix for #14919 (by deleting a few lines of code, of course :), but that should be a future PR.