Skip to content
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

Specialization on unused arguments #23753

Closed
cstjean opened this issue Sep 18, 2017 · 9 comments
Closed

Specialization on unused arguments #23753

cstjean opened this issue Sep 18, 2017 · 9 comments

Comments

@cstjean
Copy link
Contributor

cstjean commented Sep 18, 2017

Julia 0.6 specializes on unused arguments:

julia> foo(a, b) = a
foo (generic function with 1 method)

julia> foo(10, 2)
10

julia> foo(10, 1.0)
10

julia> specializations(foo)
2-element Array{Core.MethodInstance,1}:
 MethodInstance for foo(::Int64, ::Float64)
 MethodInstance for foo(::Int64, ::Int64)  

There might be a very good reason for this, but I couldn't find any relevant issue. Wouldn't it be more memory/time efficient to share?

@JeffBezanson
Copy link
Member

One issue is that the caller doesn't know that the function doesn't use its argument, so generating a specialized entry point can still be worthwhile for more efficient caller code. That could also be handled with a different calling convention for such a function, but that carries significant complexity. In general, functions tend to use their arguments, so spending complexity on unused arguments is probably not worthwhile.

@StefanKarpinski
Copy link
Member

If the function is as simple as this example, won't it tend to be inlined and therefore the issue is moot anyway? It seems like it would only have any effect in cases where the function is fairly beefy. So it seems like the concern here is not performance but avoiding generating the same code multiple times – i.e. don't change calling convention (pass the second argument), but automatically infer that it should be @nospecialize?

@JeffBezanson
Copy link
Member

The bottom line is that unused arguments are rare enough in practice that this probably has minimal impact. I might have done some experiments on this in the past but I'm not sure.

Without a more realistic example, it's hard to tell whether the issue is code size or performance. If the function is just over the inlining threshold, generating two copies of it could certainly be worthwhile to avoid boxing an argument on every call.

@quinnj
Copy link
Member

quinnj commented Sep 18, 2017

Yeah, at the end of the day, I think we'd rather focus effort on #11339, i.e. being able to mark certain parameters to not specialize on, which is in a similar vein to the ask here.

@cstjean
Copy link
Contributor Author

cstjean commented Sep 19, 2017

Fair enough. Julia was generating thousands of specializations of a certain function in my code, which caused very long compilation time. I couldn't avoid it through ::ANY without losing dispatch, but I was able to refactor the code to fix the issue. @nospecialize(x::Int) would have worked as well.

@cstjean cstjean closed this as completed Sep 19, 2017
@yuyichao
Copy link
Contributor

@nospecialize(x::Int)

This would have no effect. For abstract types, this will also require boxing of the argument as Jeff mentioned.

@cstjean
Copy link
Contributor Author

cstjean commented Sep 19, 2017

My issue was with compilation time getting out of hands. Wouldn't @nospecialize help with that?

@yuyichao
Copy link
Contributor

Well, ::Int is a leaftype so no.

@cstjean
Copy link
Contributor Author

cstjean commented Sep 19, 2017

🤦‍♂️ of course. I mistyped my example. I meant @nospecialize(x::Type{<:MyParametricType})

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

No branches or pull requests

5 participants