-
-
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
Major regression in in #16809
Comments
same issue as seen in #16185 we could fix this by doing something like: diff --git a/base/reduce.jl b/base/reduce.jl
index f83c86b..585876d 100644
--- a/base/reduce.jl
+++ b/base/reduce.jl
@@ -192,14 +192,14 @@ sc_finish(::typeof(|)) = false
## short-circuiting (sc) mapreduce definitions
-function mapreduce_sc_impl(f, op, itr::AbstractArray)
+function mapreduce_sc_impl(f, op::ShortCircuiting, itr::AbstractArray)
for x in itr
shortcircuits(op, f(x)) && return shorted(op)
end
return sc_finish(op)
end
-function mapreduce_sc_impl(f, op, itr)
+function mapreduce_sc_impl(f, op::ShortCircuiting, itr)
for x in itr
shortcircuits(op, f(x)) && return shorted(op)
end but I'm inclined just to go with simplifying the code instead: diff --git a/base/reduce.jl b/base/reduce.jl
index f83c86b..90ba6d1e 100644
--- a/base/reduce.jl
+++ b/base/reduce.jl
@@ -181,29 +181,19 @@ end
const ShortCircuiting = Union{typeof(&), typeof(|)}
-shortcircuits(::typeof(&), x::Bool) = !x
-shortcircuits(::typeof(|), x::Bool) = x
-
-shorted(::typeof(&)) = false
-shorted(::typeof(|)) = true
-
-sc_finish(::typeof(&)) = true
-sc_finish(::typeof(|)) = false
-
## short-circuiting (sc) mapreduce definitions
-
-function mapreduce_sc_impl(f, op, itr::AbstractArray)
+function mapreduce_sc_impl(f, op::typeof(&), itr)
for x in itr
- shortcircuits(op, f(x)) && return shorted(op)
+ f(x) || return false
end
- return sc_finish(op)
+ return true
end
-function mapreduce_sc_impl(f, op, itr)
+function mapreduce_sc_impl(f, op::typeof(|), itr)
for x in itr
- shortcircuits(op, f(x)) && return shorted(op)
+ f(x) && return true
end
- return sc_finish(op)
+ return false
end
# mapreduce_sc tests if short-circuiting is safe; |
Ha--- I have that exact change (the second one) in my working tree. |
There's an argument to avoid short-circuiting here, at least for containers that don't contain duplicates:
If you don't short-circuit, there is no branch, and you can use Containers with lots of duplicates mess with that, however. |
Seems like even with the short circuit the code should still be vectorizable. |
Sounds like an argument for a specialized function to use when no duplicates are present. |
I guess with the new hand-vectorization, that might be true (I haven't played with it yet).
Unless one introduces a special type, you can't check this without visiting all the elements anyway. From a codegen perspective, a special type would almost surely be a bad idea if it's used widely---of course, a narrow application where it really matters might be different. |
I just meant a separate function that people would call when they know there are likely very few or no duplicates. |
That's essentially |
Why shouldn't llvm be able to figure this out? |
Would be lovely. Currently LLVM can't even vectorize function anyneg_nobranch(v)
hasneg = false
@simd for i in eachindex(v)
@inbounds val = v[i]
hasneg |= val < 0
end
hasneg
end although it does handle function anyneg_nobranch(v)
nneg = 0
@simd for i in eachindex(v)
@inbounds val = v[i]
nneg += val < 0
end
nneg > 0
end It's fairly clear why the first is harder than the second, but it does suggest that the vectorization is not yet Sufficiently Smart. |
fix #16809, perf regression in `in`
I found a large regression between 0.4 and 0.5 in some code of mine, which profiling localized to containment testing. This simplified test case shows a clear picture:
The text was updated successfully, but these errors were encountered: