Skip to content

Conversation

@maleadt
Copy link
Member

@maleadt maleadt commented Jul 15, 2022

Fixes #46049. Not sure what a good test would be, as this does infer correctly.

cc @OlivierHnt

@maleadt maleadt added performance Must go faster backport 1.8 Change should be backported to release-1.8 labels Jul 15, 2022
@maleadt maleadt marked this pull request as ready for review July 15, 2022 14:06
@gbaraldi
Copy link
Member

Maybe add a test so that this won't be regressed in the future?

@maleadt
Copy link
Member Author

maleadt commented Jul 15, 2022

Not sure what a good test would be, as this does infer correctly.

Any suggestions? string-matching code_llvm output isn't pretty.

@gbaraldi
Copy link
Member

What about something like your example, if there are dynamic dispatches there will be allocation so
@allocated(kernel()) == 0

@maleadt maleadt force-pushed the tb/tuple_getindex branch from 1e6bd35 to 75b5ddb Compare July 15, 2022 15:22
@N5N3
Copy link
Member

N5N3 commented Jul 15, 2022

Not sure what a good test would be, as this does infer correctly.

kernal() is stable just because the wrapper implies an annotation. We can test setindex(::Tuple)'s stability directly:

julia> Base.return_types(Base.setindex, Tuple{NTuple{16,Int},Int,Int})
1-element Vector{Any}:
 Tuple{Vararg{Int64}}  #  NTuple{16, Int64} after this PR

The improvement comes from the fact that ntuple(f, ::Val) is a generated function.
While ntuple(f, n::Int) only tries to const-propagation when n<=10.
So I believe that we don't need _setindex. The following version seems working well

function setindex(x::Tuple, v, i::Integer)
    @boundscheck 1 <= i <= length(x) || throw(BoundsError(x, i))
    @inline
    ntuple(j -> ifelse(j == i, v, x[j]), Val(length(x)))
end

@maleadt
Copy link
Member Author

maleadt commented Jul 18, 2022

So I believe that we don't need _setindex. The following version seems working well

Thanks, I've pushed this version.

@maleadt maleadt force-pushed the tb/tuple_getindex branch from 141167e to 8fd8823 Compare July 18, 2022 10:09
@N5N3
Copy link
Member

N5N3 commented Jul 19, 2022

Sorry for my recklessness, we still need _setindex to skip boundscheck in selectdim. Has been fixed.

@maleadt
Copy link
Member Author

maleadt commented Jul 19, 2022

we still need _setindex to skip boundscheck in selectdim

Why not add @inbounds to the setindex call?

@N5N3
Copy link
Member

N5N3 commented Jul 19, 2022

Why not add @inbounds to the setindex call?

We test Base with --check-bounds=yes thus @inbounds would be ignored during CI.

$(call PRINT_JULIA, $(call spawn,$(JULIA_EXECUTABLE)) --check-bounds=yes --startup-file=no --depwarn=error ./runtests.jl $@)

@maleadt
Copy link
Member Author

maleadt commented Jul 19, 2022

We test Base with --check-bounds=yes thus @inbounds would be ignored during CI.

Ah, I thought it was a performance consideration, and didn't realize it actually triggers during CI. I'm not sure it's worth reusing _setindex for that, but 🤷

@maleadt maleadt force-pushed the tb/tuple_getindex branch from 4fa5ec6 to ceed845 Compare July 19, 2022 15:56
@maleadt
Copy link
Member Author

maleadt commented Jul 19, 2022

I've rebased-out your change and revert, @N5N3, because it included a bit of unnecessary churn. I've left the explicit ::VarArgs{N} in so that we ensure specialization instead of relying on constant-propagation to the Val constructor.

@N5N3
Copy link
Member

N5N3 commented Jul 20, 2022

I think we'd better avoid unnecessary splat. As our compiler might refuse to inline _setindex if x is too long (>=33)

julia> a = ntuple(identity, 33);

julia> @btime setindex($a, 1, 1);
  352.995 ns (2 allocations: 544 bytes)  # no splat : 3.200 ns (0 allocations: 0 bytes)

@KristofferC
Copy link
Member

I'll take this as a fix for the regression, further improvements can of course be made as follow ups.

@KristofferC KristofferC merged commit d7c56ba into master Jul 20, 2022
@KristofferC KristofferC deleted the tb/tuple_getindex branch July 20, 2022 08:08
KristofferC pushed a commit that referenced this pull request Jul 20, 2022
@KristofferC KristofferC removed the backport 1.8 Change should be backported to release-1.8 label Aug 7, 2022
ffucci pushed a commit to ffucci/julia that referenced this pull request Aug 11, 2022
pcjentsch pushed a commit to pcjentsch/julia that referenced this pull request Aug 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Must go faster

Projects

None yet

Development

Successfully merging this pull request may close these issues.

setindex(::Tuple) performance regression

5 participants