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

rand is slow #114

Open
jw3126 opened this issue May 20, 2016 · 3 comments
Open

rand is slow #114

jw3126 opened this issue May 20, 2016 · 3 comments

Comments

@jw3126
Copy link

jw3126 commented May 20, 2016

Random number generation is currently slow in some cases. An extreme example is the following:

using FixedSizeArrays

function f(N)
    for _ in 1:N
        rand(Mat{6,4, Int64}, 1:10)
    end
end

function g(N)
    for _ in 1:N
        rand(1:10, 6, 4)
    end
end
f(1)
g(1)
N = 10^6
@time f(N) # 1.481381 seconds (4 allocations: 160 bytes)
@time g(N) # 0.443486 seconds (2.00 M allocations: 274.658 MB, 2.93% gc time)

Despite having huge memory allocation, the Array variant is still faster.

@c42f
Copy link
Collaborator

c42f commented May 21, 2016

Hmm odd, this is true (though less severe) even when using Vec{3, Int64}.

@SimonDanisch
Copy link
Owner

After some detective work: turns out that the rand function that does all the work doesn't get inlined and also, the current code seems to copy the range for every call to rand (whaat?!).

julia>using FixedSizeArrays, BenchmarkTools
julia> function tm()
       r = 1:10
       Mat{6,4,Int}(
       (rand(r), rand(r), rand(r) ,rand(r), rand(r), rand(r)),
       (rand(r), rand(r), rand(r) ,rand(r), rand(r), rand(r)),
       (rand(r), rand(r), rand(r) ,rand(r), rand(r), rand(r)),
       (rand(r), rand(r), rand(r) ,rand(r), rand(r), rand(r)),
       )
       end
tm (generic function with 1 method)

julia> function tm2()
       r = Base.Random.RangeGenerator(1:10)
       g = Base.GLOBAL_RNG
       Mat{6,4,Int}(
       (rand(g,r), rand(g,r), rand(g,r) ,rand(g,r), rand(g,r), rand(g,r)),
       (rand(g,r), rand(g,r), rand(g,r) ,rand(g,r), rand(g,r), rand(g,r)),
       (rand(g,r), rand(g,r), rand(g,r) ,rand(g,r), rand(g,r), rand(g,r)),
       (rand(g,r), rand(g,r), rand(g,r) ,rand(g,r), rand(g,r), rand(g,r)),
       )
       end

tm2 (generic function with 1 method)

julia> function test()
              x = 1:10
              b = @benchmark rand($x)
              r1 = median(b.times)
              rg = Base.Random.RangeGenerator(x)
              b = @benchmark rand($(Base.GLOBAL_RNG), $rg)
             r2 = median(b.times)
              b = @benchmark tm()
              fsa1 = median(b.times)
              b = @benchmark tm2()
              fsa2 = median(b.times)
             b = @benchmark rand($(Mat{6,4, Int}), $x)
             fsa3 = median(b.times)
              b = @benchmark rand($x, 6,4)
             a1 = median(b.times)
              println("pure rand ", r1)
              println("special rand ", r2)
              println("theoretical max with pure rand for current impl: ", fsa3/r1/(6*4), " handrolled ", fsa1/r1/(6*4))
              println("theoretical max with special rand for special handrolled ", fsa2/r2/(6*4))
              end
julia>test()
pure rand 41.0
special rand 22.0
theoretical max with pure rand for current impl: 2.0863821138211383 handrolled 0.9664634146341463
theoretical max with special rand for special handrolled 0.9526515151515151

@jw3126
Copy link
Author

jw3126 commented May 21, 2016

Thanks for investigating this! I am confused. If I understand your benchmark correctly, a max speed up of 2x (or 4x for special) could theoretically be gained?
But the stupid rand(1:10, 6, 4) version was already nearly 3x as fast?

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

No branches or pull requests

3 participants