Earlier quoted context omitted.
Probably because Go version is different, compare C vector operations with Go vector operations. C version is operating on pointer without allocating new vector, Go version is allocation new vector on every op. EDIT: Look at C code assembly, it's generating mostly SIMD instructions and using xmm registers. That's why it's faster. Golang compiler still do not have autovectorization implemented that's why it's so much…
I modified the Go version to pass references (see my second edit) and that made up the difference (or I mistranslated).
Programming language ray tracing benchmarks project
61–70 of 90 posts
Re: Programming language ray tracing benchmarks project
#62This times performance like this: $ time ./crb That means time spent writing the .ppm file is included. In the implementations I browsed, that is about a million print calls, each of which might flush the output buffer, and whose performance may depend on locale. To benchmark ray tracing I would, instead, just output the sum of the pixel values, or set the exit code depending on that value. Even though ray tracing is…
Re: Programming language ray tracing benchmarks project
#63> rustc 1.13.0-nightly what's an ancient version of rust. Interesting it is faster than C, though.
Re: Programming language ray tracing benchmarks project
#64Interesting that Nim is slightly faster than C it considering that it compiles down to C.
That's possibly because of the "Code must follow best practices" restriction. Oftentimes compile to C is "It's C Jim, but not as we know it" You can write C as if it is a SSA VM or similar intermediate representation that leaves very little work for the first stages of the compiler.
Re: Programming language ray tracing benchmarks project
#65Earlier quoted context omitted.
Different languages' benchmarks might not be equally well-written / optimized. In particular, I'd expect C and Rust to be very close to each other, and a 20% gap between them is a red flag. Rules like "code should be simple, as in, easy to read and understand" are also hard to judge, especially near the top of the list where there's a lot of pressure to optimize. Is SIMD easy to understand? What if it's in a library?…
Not necessarily. Because C allows the pointer manipulation, the compiler can in general not make assumptions about pointer aliasing. This prevents some optimizations. In Rust, the compiler has more information/control over memory layout/lifetime and can therefore make stronger optimizations. Automatic vectorization is an area where this helps a lot, and raytracing can benefit a lot here. 20% sounds reasonable to me.
Unfortunately, due to LLVM bugs, the Rust developers had to disable that optimization, more than once. I don't know whether the "1.13.0-nightly" he used has that optimization enabled or disabled. (See https://github.com/rust-lang/rust/issues/31681 and https://github.com/rust-lang/rust/issues/54878 for the relevant Rust issues.)
Re: Programming language ray tracing benchmarks project
#66Earlier quoted context omitted.
I modified the Go version to pass references (see my second edit) and that made up the difference (or I mistranslated).
Ah, you replied to my comment before the edit, about unnecessary allocation in Go vec handling.
Re: Programming language ray tracing benchmarks project
#67Ordered by realtime, fastest to slowest for those like me who got annoyed by the scrolling up and down trying to compare: Rust (1.13.0-nightly) 1m32.392s Nim (0.14.2) 1m53.320s C 1m59.116s Julia (0.4.6) 2m01.166s Crystal (0.18.7) 2m01.735s C Double Precision 2m26.546s Java (1.7.0_111) 2m36.949s Nim Double Precision (0.14.2) 3m19.547s OCaml 3m59.597s Go 1.6 6m44.151s node.js (6.2.1) 7m59.041s node.js (5.7.1) 8m49.170s…
I wouldn’t give much weight to those benchmark numbers at this point. Some of those language versions are quite out of date...
crb-omp 0m22.949s
crb 0m23.240s
crb_opt 0m31.404s
nimrb_pmap 0m8.828s
nimrb_fn 0m22.988s
nimrb 0m26.556s
The base C code is faster than base Nim code. The optimised C code is significantly slower than everything else(!?). The Nim program that uses a threadpool is the fastest of these.I couldn't get the CPP versions to compile. I'll do the Rust programs some other time.
Re: Programming language ray tracing benchmarks project
#68Ordered by realtime, fastest to slowest for those like me who got annoyed by the scrolling up and down trying to compare: Rust (1.13.0-nightly) 1m32.392s Nim (0.14.2) 1m53.320s C 1m59.116s Julia (0.4.6) 2m01.166s Crystal (0.18.7) 2m01.735s C Double Precision 2m26.546s Java (1.7.0_111) 2m36.949s Nim Double Precision (0.14.2) 3m19.547s OCaml 3m59.597s Go 1.6 6m44.151s node.js (6.2.1) 7m59.041s node.js (5.7.1) 8m49.170s…
That's a big jump between OCaml and Go. I'm not familiar with ray tracing, but skimming the source code it mostly looks like it's doing floating point math; it doesn't look like it's using the runtime (no allocations, no virtual function calls, no scheduling, etc), so I'm surprised that Go is performing relatively poorly. I wonder if the performance gap is attributable to some overhead in Go's function calls? I know…
- initial time: 49s
- replacing default thread-safe RNG with rand.New sliced 6 seconds off. (the default RNG uses mutexes), = 43s
- use float64 instead of float32 and remove many type conversions. Another two seconds off. = 41s.
As others suggested, go still lacks many compile time optimizations and the implementation could be improved.
Re: Programming language ray tracing benchmarks project
#69The haskell version can be made >= 3x faster by making the computations non-lazy, e.g. -data Vector3 = Vector3 {vx::Float, vy::Float, vz::Float} deriving (Show) +data Vector3 = Vector3 {vx :: !Float, vy :: !Float, vz :: !Float} deriving (Show)
This seems like a nice improvement, could you send a PR for it?