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

Add Rust comparison #3

Merged
merged 4 commits into from
Dec 7, 2022

Conversation

andrewjradcliffe
Copy link
Contributor

As a result of JuliaLang/julia#47715, I noticed this repository and thought: why not add a Rust comparison?

For this addition to work, one would need to have rustc and cargo installed.

As a result of JuliaLang/julia#47715, I
noticed this repository and thought: why not add a Rust comparison?

For this addition to work, one would need to have `rustc` and `cargo`
installed.
Copy link
Owner

@LilithHafner LilithHafner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! This is great. It ran without hiccup on my machine. Once this merges, I'll regenerate all the data and update the figure.

src/script_rs/src/main.rs Show resolved Hide resolved
src/script_rs/src/main.rs Show resolved Hide resolved
src/script_rs/src/main.rs Outdated Show resolved Hide resolved
src/script_rs/Cargo.toml Show resolved Hide resolved

[dependencies]
rand = "0.8.5"
rand_xoshiro = "0.6.0"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you choose to use rand_xoshiro rather than the rust stdlib's random number generation? Performance shouldn't be an issue so long as it is substantially faster than sorting because we subtract the runtime of g from the runtime of f..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust's stdlib does not include random number generators. rand provides a number of things, but not xoshiro generators -- rand_xoshiro is part of the rust-random org. The implementations are identical to David Blackman and Sebastiano Vigna's implementations (see linked code, other interesting things at https://prng.di.unimi.it/#intro).

I specifically chose xoshiro256++ as this is the default (since 1.7) generator used by Julia's Random stdlib. My objective was to replicate the PRNG behavior as closely as possible between the two. The implementations of Julia's xoshiro256++ and rand_xoshiro's are identical, thus, the statistical properties are identical in that respect; the seeding procedure are slightly different (but both use OS entropy at their core), so that's one source of variation that can't conveniently be locked down.
Additionally, Julia uses SIMD bulk generation with xoshiro256++ when filling arrays (i.e. for calls of the form rand!(::AbstractArray{Float64})) of bits types such as Float64, UInt64, etc. I am not certain that rustc will SIMD the loop body inside the fill call -- I'd need to examine the assembly; based on the source code, it does not seem likely unless some very aggressive inlining takes place. Note that it would be straightforward to guarantee if we use portable_simd and nightly Rust, but that would still not necessarily yield the same behavior as Julia's bulk generation.

The easy way to force the generated sequences to be identical is to provide identical initial states (256 bits, which Julia takes as 4 UInt64s and Rust as a static array of UInt8s), and for each i=1:N, i=1:m advance the state using the jump function. Additionally, to opt out of Julia's SIMD bulk generation, replace the rand! calls with something like

function elementwiserand!(rng, z::AbstractArray{T}) where {T}
    for i  eachindex(z)
        z[i] = rand(rng, T)
    end
    z
end

The details above are superfluous for this purpose, but if one is going to benchmark sorting algorithms -- which can be sensitive to patterns (or lack thereof) in data -- it is worthwhile to consider such aspects.

src/script_rs/.gitignore Outdated Show resolved Hide resolved
@LilithHafner
Copy link
Owner

Rust is the first non-julia language that is consistently faster than Julia 1.8.3 for large sizes!

See the updated figure at: https://github.com/LilithHafner/InterLanguageSortingComparisons/tree/update-figure

@andrewjradcliffe
Copy link
Contributor Author

Rust is the first non-julia language...

Once this PR is merged, I can add a threaded version of the above (very minor modification using rayon) -- for when you get around to adding multi-threaded sorting to Julia.

@LilithHafner LilithHafner merged commit a22f853 into LilithHafner:main Dec 7, 2022
@LilithHafner LilithHafner mentioned this pull request Dec 7, 2022
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

Successfully merging this pull request may close these issues.

2 participants