Why is Rust n-body benchmark slower than C++?


#1

According to n-body benchmark Rust is more than 2 times slower here than C++ and C. Why is that? It looks like it is very math-heavy code where Rust should excel and compile to mostly same code.

Is it problem of code or Rust lacks some optimizations?

http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=rust&id=1


#2

A couple of thoughts looking at the code, the C++ version does not have to ‘match’ inside the loop, and is using vectorised operators.

Does rust have vector operators, that compile to SIMD instructions? Even if Rust had auto-vectorization it cannot get near the performance of direct vector operations.


#3

There’s a faster SIMD version of n-body as an example in the simd crate.


#4

why is it not submitted yet?


#5

I’m guessing because the benchmarks aren’t exactly well-maintained. The project is using a Makefile for building rather than using cargo, which makes it harder to make contributions. The written code is also in bad form (lots of clippy warnings)


#6

It requires unstable code (i.e. one must use a nightly compiler), while I believe the website sensibly uses only stable.


#7

n-body Rust #2 program

14.600s rustc 1.7.0
24.533s rustc 1.8.0

?


#8

Yes, that’s some serious performance degradation. Perhaps someone should look into it.


#9

I would open a ticket for this.


#10

just wanted to say, i tried it myself and got very different numbers.

on the website it says

  • C++: 9.30
  • rust: 24.07
  • Go: 21.73

i just copy/pasted the source-code and ran it on my vm:

rustc 1.13.0-nightly (1576de0ce 2016-08-21)
go version go1.7 linux/amd64
building C++: ..
building rust: cargo build --release
    Finished release [optimized] target(s) in 0.0 secs
building go: go build -o nbody-go
running C++: time ./nbody.gpp-3.gpp_run 50000000
-0.169075164
-0.169059907

real    0m5.197s
user    0m5.196s
sys     0m0.000s
running rust: time target/release/shootout-nbody 50000000
-0.169075164
-0.169059907

real    0m7.000s
user    0m6.996s
sys     0m0.000s
running go: time ./nbody-go 50000000
-0.169075164
-0.169059907

real    0m9.206s
user    0m9.224s
sys     0m0.004s

#11

See also the n-body code here:


#12

this is really nice to learn, thank you!

i tried your code and got this:

running 50000000x
----------------------------------------- versions
g++ (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rustc 1.13.0-nightly (1576de0ce 2016-08-21)
go version go1.7 linux/amd64
----------------------------------------- rust-1
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=rust&id=1
-0.169075164
-0.169059907

real    0m6.902s
user    0m6.896s
sys     0m0.004s
----------------------------------------- rust-2
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=rust&id=2
-0.169075164
-0.169059907

real    0m6.897s
user    0m6.892s
sys     0m0.000s
----------------------------------------- rust-3
https://internals.rust-lang.org/t/loop-unrolling-on-request/3091
-0.169075164
-0.169059907

real    0m6.416s
user    0m6.404s
sys     0m0.004s
----------------------------------------- rust-4
https://internals.rust-lang.org/t/loop-unrolling-on-request/3091
-0.169075164
-0.169059907

real    0m5.032s
user    0m5.008s
sys     0m0.020s
----------------------------------------- go-1
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=go&id=1
-0.169075164
-0.169059907

real    0m8.958s
user    0m8.988s
sys     0m0.000s
----------------------------------------- C++-3
http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=gpp&id=3
-0.169075164
-0.169059907

real    0m5.163s
user    0m5.160s
sys     0m0.000s