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

Type-parameterize Core.Box #53382

Closed
wants to merge 1 commit into from
Closed

Type-parameterize Core.Box #53382

wants to merge 1 commit into from

Conversation

uniment
Copy link

@uniment uniment commented Feb 19, 2024

This edit aims to take a small step toward solving some of the issues in #15276.

There are performance optimizations that do not occur when Box accesses are merely typeasserted, which instead require the box to be type-parameterized (example).

This edit type-parameterizes Core.Box, and then future improvements leveraging type annotations and inference can build on top of that.

@giordano
Copy link
Contributor

Why this PR is changing permissions to 28 (out of 31) unrelated files, breaking the build process?

@uniment
Copy link
Author

uniment commented Feb 19, 2024

This is a practice run as I get warmed up. My setup got messed up somehow, I'm going to scratch the whole thing.

@uniment uniment closed this Feb 19, 2024
@KristofferC
Copy link
Sponsor Member

In order for something like this to happen I think it needs to be "proved" that the compiler can take advantage of it and actually generate useful parameterized Boxes in cases where it would otherwise not.

@uniment
Copy link
Author

uniment commented Feb 19, 2024

Oh, it appears that in Julia 1.10 the performance penalty that existed for unparameterized Box has been eliminated

Before:

julia> VERSION
v"1.9.4"

julia> @btime (()->begin # parameterized box
           x = Ref(1)
           f() = (x[] = x[] + 1; x[])
           for i=1:1000; f() end
           x[]
       end)()
  1.800 ns (0 allocations: 0 bytes)
1001

julia> @btime (()->begin # typeassert'ed box
           x::Int = 1
           f() = (x = x+1; x)
           for i=1:1000; f() end
           x
       end)()
  4.457 μs (490 allocations: 7.66 KiB)
1001

Now:

julia> VERSION
v"1.10.1"

julia> @btime (()->begin # parameterized box
           x = Ref(1)
           f() = (x[] = x[] + 1; x[])
           for i=1:1000; f() end
           x[]
       end)()
  2.000 ns (0 allocations: 0 bytes)
1001

julia> @btime (()->begin # typeassert'ed box
           x::Int = 1
           f() = (x = x+1; x)
           for i=1:1000; f() end
           x
       end)()
  1.800 ns (0 allocations: 0 bytes)
1001

@uniment
Copy link
Author

uniment commented Feb 19, 2024

On second look, it appears that even in Julia 1.12 there is still a performance penalty for asserted but unparameterized Box:

julia> VERSION
v"1.12.0-DEV.17"

julia> @btime let a::Int=0; for i=1:1000; a+=i end; ()->a+=1 end;
  5.000 μs (970 allocations: 15.16 KiB)

Compare with what is possible by type-parameterizing the box:

julia> @btime let a=Core.Box{Int}(0); for i=1:1000; a.contents+=i end; ()->a.contents+=1 end;
  4.300 ns (1 allocation: 16 bytes)

(notice microseconds vs nanoseconds)

This pull request was closed.
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

Successfully merging this pull request may close these issues.

3 participants