-
-
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
julep: a return-able break
statement (improving iteration performance)
#16035
Comments
Hmm, I just thought of another alternative: define a 3-argument, 2-return
This would allow one, as needed, to override the 3-argument version and use This appears to be completely non-breaking and would seemingly solve the performance problem. In a sense this sort of gives us #9182, except that #9182 doesn't solve this particular performance problem. |
break
statement (improving iteration performance)
This latter proposal also seems likely to solve #8149: just set up the iterator so the |
break
statement (improving iteration performance)
Continuing my debate with myself...now I'm skeptical that the 3-argument, 2-return Might be good for #8149, though. |
Looks like we use an LLVM optimization pass, jump threading, that might possibly help here. But the performance suggests it's not achieving this particular goal. Test code: function sumcart_while_maybe(A::AbstractMatrix)
@assert !isempty(A)
s = 0.0
i = j = 1
@inbounds while true
s += A[i,j]
mightbreak = false
i += 1
if i > size(A, 1)
i = 1
j += 1
mightbreak = true
end
if mightbreak
if j > size(A, 2)
break
end
end
end
s
end Ideally LLVM would take that function sumcart_while_good(A::AbstractMatrix)
@assert !isempty(A)
s = 0.0
i = j = 1
@inbounds while true
s += A[i,j]
i += 1
if i > size(A, 1)
i = 1
j += 1
if j > size(A, 2)
break
end
end
end
s
end Anyone know of any other passes that might help? |
Reflecting on #16035 (comment) further, if the increment in |
Closed in favor of an explicit solution, #16878. |
I looked into #9080 again, and as pointed out by @simonster, it seems obvious that the core problem is that our current iteration framework seems to require two branches per iteration rather than one. It seems this could be solved if we could, in effect, return
break
from a function.The performance difference is illustrated by these functions:
The
good
one typically has only one branch per iteration, whereas thebad
one always has two. Thegood
one has the same performance as writing the loops out manually, and thebad
one is about 70% worse.In this gist I present some code which would generate the
good
version, if we were able to "call"break
from inside a function. (CR
=CartesianRange
,CI
=CartesianIndex
.) Note this is not the same as effectively testingdone
insidenext
, and just passing back the boolean; the key problem is the branch, not the comparison.Note the gist is also free of
@generated
functions; we can do that regardless, of course.The text was updated successfully, but these errors were encountered: