-
-
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
Dot product with sub() slow for small ranges #15961
Comments
What you are looking for is #14955, see also https://groups.google.com/forum/#!msg/julia-users/6Z1kJ5LrSMU/_HcWLsubBAAJ Also, fyi, this will make your loop version a bit faster (so it is not slower than function dot5{T}(U::Matrix{T}, V::Matrix{T}, i, j)
s = zero(T)
@inbounds @simd for k in 1:size(U,1)
s += U[k, i] * V[k, j]
end
return s
end |
It's considerably better if you time a function rather than at global scope, see below (requires julia-0.5 to be efficient). But still far from ideal. This can't be fixed without #12205; basically the issue is that the SubArray type needs to hold a reference to the parent array, and since that's not a Modified test code: dot1(U, V, i, j) = dot(U[:,i], V[:,j])
dot2(U, V, i, j) = sum([U[k,i]*V[k,j] for k=1:size(U,1)])
dot3(U, V, i, j) = dot(sub(U, :, i), sub(V, :, j))
function dot4(U, V, i, j)
r = 0.0
for k=1:size(U,1)
r += U[k,i]*V[k,j]
end
r
end
function rundot(f, U, V, n)
size(U) == size(V) || throw(DimensionMismatch("Matrices have different sizes"))
rng = 1:size(U, 2)
s = 0.0
for k = 1:n
s += f(U, V, rand(rng), rand(rng))
end
s
end
for (p, n) in [(25, 1000000), (250, 100000), (2500, 10000)]
U, V = randn(p, 10000), randn(p, 10000)
# Compile functions and check that they work
@assert dot1(U, V, 1, 1) dot2(U, V, 1, 1) dot3(U, V, 1, 1) dot4(U, V, 1, 1)
for f in (dot1, dot2, dot3, dot4)
rundot(f, U, V, 1)
end
println("(p, n) = ($p, $n)")
@time rundot(dot1, U, V, n)
@time rundot(dot2, U, V, n)
@time rundot(dot3, U, V, n)
@time rundot(dot4, U, V, n)
end Results:
|
Since there's nothing to do and this will be "automatically" fixed by #12205, I'm closing this. |
Hello,
I'm a new user of Julia, I've been using it for the past 3 months and I recently started using it for university.
Right now I'm doing a project in which I have matrices of size
p×n
, withp
small andn
large, and I need to perform hundreds of thousands of dot products between random columns of these matrices. My code being too slow, I was looking for a bottleneck and found that it was becauseU[:,i]
actually performed a copy. I tried usingsub
but the results weren't satisfying either. I decided to test different ways of computing my dot product, and found that the fastest way to do it was to do a simple loop with an accumulator.Here is my benchmark code:
And here is the result, on my computer:
For large values of
p
, the observed behaviour is the one I expected:dot
withsub
is fastest. But for smaller values, it's barely faster than a list comprehension, and the loop with an accumulator is fastest. I don't know if this is the expected behaviour forsub
, but it seems like a performance bug. I suppose there must be an overhead associated withsub
. Is there a way to index an array in a "C-pointer-like" way, without overhead? That would most certainly fix the issue.The text was updated successfully, but these errors were encountered: