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

Document type specialization #23471

Closed
cstjean opened this issue Aug 27, 2017 · 10 comments
Closed

Document type specialization #23471

cstjean opened this issue Aug 27, 2017 · 10 comments
Labels
docs This change adds or pertains to documentation

Comments

@cstjean
Copy link
Contributor

cstjean commented Aug 27, 2017

On 0.6.0,

foo1(t::Type, x)            = Nullable{t}(sin(x))
foo2(t::Type{T}, x) where T = Nullable{t}(sin(x))

@btime foo1(Float64, 2)
  408.815 ns (2 allocations: 48 bytes)    # same with @allocated
@btime foo2(Float64, 2)
  17.359 ns (0 allocations: 0 bytes)

However, both functions are @inferred correctly, and have the same @code_llvm. Why does foo1 allocate?

Might be related to #19137

@KristofferC
Copy link
Member

@cstjean
Copy link
Contributor Author

cstjean commented Aug 27, 2017

Does that issue affect @allocated? It reports 48 bytes for foo1 and 0 for foo2.

@KristofferC
Copy link
Member

KristofferC commented Aug 27, 2017

I didn't see the @allocated comment but I think the problem is when another function calls foo e.g:

f1() = foo1(Float64, 2)
f2() = foo2(Float64, 2)

and look at generated code for f1and f2.

@yuyichao yuyichao added the docs This change adds or pertains to documentation label Aug 27, 2017
@yuyichao yuyichao changed the title ::Type specialization Document ::Type specialization Aug 27, 2017
@yuyichao yuyichao changed the title Document ::Type specialization Document type specialization Aug 27, 2017
@cstjean
Copy link
Contributor Author

cstjean commented Aug 27, 2017

That makes sense. Can anyone please explain to me how f1/foo1 can be type-stable, if the argument isn't being specialized on? My guess is that it's type-stable because Julia runs inference to get the output type of foo1(Float64, 2) and foo1(Int, 2), even if it compiles only one "method specialization" for these two. That specialization's return value's type is Nullable(_), and that's why it allocates the result on the heap. Is that right?

@yuyichao
Copy link
Contributor

Can anyone please explain to me how f1/foo1 can be type-stable, if the argument isn't being specialized on?

Type stable means that the inference can know what the return (or other variable) type is (are). Specialize means the compiler generate code for a specific input. The latter requires the former but is not implied by it. We do more inference than specialization to avoid excess code generation.

@cstjean
Copy link
Contributor Author

cstjean commented Sep 11, 2017

MyType{T} = Type{T}
MyType2 = Type

foo1(t::Type, x)    = Nullable{t}(sin(x))
foo3(t::MyType, x)  = Nullable{t}(sin(x))
foo4(t::MyType2, x) = Nullable{t}(sin(x))

@btime foo1(Float64, 2)
  408.815 ns (2 allocations: 48 bytes)
@btime foo3(Float64, 2)
  17.358 ns (0 allocations: 0 bytes)
@btime foo4(Float64, 2)
  349.832 ns (2 allocations: 48 bytes)

MyType == MyType2  # true

While I can see where these results are coming from, it's very subtle behavior, with a large performance impact.

@KristofferC
Copy link
Member

Don't you need a const on the MyType2?

@cstjean
Copy link
Contributor Author

cstjean commented Sep 11, 2017

Same results.

@KristofferC
Copy link
Member

Oh yeah, it's only used in the function definition.

@KristofferC
Copy link
Member

Dup of #32834.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This change adds or pertains to documentation
Projects
None yet
Development

No branches or pull requests

3 participants