Rfcs: Consider using an embedded libm

Created on 23 Jan 2015  路  9Comments  路  Source: rust-lang/rfcs

Issue by cmr
_Monday Dec 02, 2013 at 20:41 GMT_

_For earlier discussion, see https://github.com/rust-lang/rust/issues/10774_

_This issue was labelled with: I-wishlist in the Rust repository_


For performance and consistency reasons, we might want to bundle our own libm. It further reduces our dependency on system libraries, opens the potential for LTO, and gives us something we can control and define.

A good candidate is openlibm, which has a long history.

See https://github.com/mozilla/rust/issues/5702, https://github.com/mozilla/rust/issues/1222

T-compiler

Most helpful comment

How does such option would look like? Is it a compile-time rust flag?

Yes, I would suggest it's a compile-time option for rust itself -- in other words, not as a flag for general users of rustc, but for distribution maintainers building rust itself.

I personally prefer to see more efforts spend on optimizing rust implementation of the math functions.

But that's exactly why it's important. A build-time option for the use of a native libm allows work to proceed efficiently in a native rust implementation while giving distribution maintainers a way to avoid significant regressions in performance for platforms that have not yet been optimized.

It also allows easy regression testing since you can then easily compare test runs between a version of rust built with native libm and one without.

It's important to not underestimate the decades of man years that have gone into implementing and optimizing libm on some architectures/platforms.

It's also important to remember that inlining is an optimization, not a requirement for correctness and has its own tradeoffs.

All 9 comments

:+1: This would solve MSVC compatibility issues, speed up our floating point operations, and greatly simplify cross-compiling.

Too bad this was exiled here. Openlibm would be nice.

Another option wold be implement libm functions in pure Rust. math.rs made a good progress in this area.

Worth noting that cargo test on math.rs fails with numerous cases of https://github.com/rust-lang/rust/issues/31407, probably making it a prerequisite if we were to go this route.

For the sake of distribution maintainers, it would be preferable if there was an option to continue using the system libm instead. For more specialized platforms, libm is often uniquely optimized already for its native architecture. While I applaud the desire to reduce dependencies, libm is not generally a target I would be concerned about.

How does such option would look like? Is it a compile-time rust flag?

I personally prefer to see more efforts spend on optimizing rust implementation of the math functions. Such as using asm! with float instructions directly. It should not be very difficult to implement the functions like cos and sin with x86 FPU instructions. In fact with ability of rust/llvm to inline these function performance should be superior with what you get with libm.

How does such option would look like? Is it a compile-time rust flag?

Yes, I would suggest it's a compile-time option for rust itself -- in other words, not as a flag for general users of rustc, but for distribution maintainers building rust itself.

I personally prefer to see more efforts spend on optimizing rust implementation of the math functions.

But that's exactly why it's important. A build-time option for the use of a native libm allows work to proceed efficiently in a native rust implementation while giving distribution maintainers a way to avoid significant regressions in performance for platforms that have not yet been optimized.

It also allows easy regression testing since you can then easily compare test runs between a version of rust built with native libm and one without.

It's important to not underestimate the decades of man years that have gone into implementing and optimizing libm on some architectures/platforms.

It's also important to remember that inlining is an optimization, not a requirement for correctness and has its own tradeoffs.

It's important to not underestimate the decades of man years that have gone into implementing and optimizing libm on some architectures/platforms.

Nobody is going to throw this work. In fact people are looking at other libm implementations (e.g. openlibm) as a source of inspiration for their work.

I ran benchmarks (Arch Linux at i7-6700k) for math.rs functions and the numbers look good:

test cos::tests::bench_libm_cos   ... bench:     425,216 ns/iter (+/- 8,270)
test cos::tests::bench_rust_cos   ... bench:     384,177 ns/iter (+/- 26,208)
test logb::tests::bench_libm_logb ... bench:      32,722 ns/iter (+/- 2,483)
test logb::tests::bench_rust_logb ... bench:      19,848 ns/iter (+/- 4,874)
test sqrt::tests::bench_asm_sqrt  ... bench:      63,176 ns/iter (+/- 2,326)
test sqrt::tests::bench_libm_sqrt ... bench:      48,252 ns/iter (+/- 3,995)
test sqrt::tests::bench_rust_sqrt ... bench:   1,788,532 ns/iter (+/- 4,608,424)

The straight-forward sqrt algorithm implementation in rust is slow but after I added one-line asm! implementation that uses sqrtsd instruction it got much better.

it's a compile-time option for rust itself -- in other words, not as a flag for general users of rustc, but for distribution maintainers building rust itself

I think it is better to leave this kind of decisions to application developers as they know better requirements for their use-cases.

It also allows easy regression testing since you can then easily compare test runs between a version of rust built with native libm and one without.

It does not have to be a compile time option. Rust allows to use C bindings easily. Actually comparing results with libm for correctness is what m tests do.

It's also important to remember that inlining is an optimization, not a requirement for correctness and has its own tradeoffs.

You keep repeating argument that a libraries implemented in Rust are incorrect and slow but I do not understand what makes you believe so. I propose to implement a fast and correct math library in pure Rust.

I think it is better to leave this kind of decisions to application developers as they know better requirements for their use-cases.

To be clear, I only suggested a rust compile-time build option as a minimum -- if the rust maintainers are willing to extend that capability to per-application, that's great.

You keep repeating argument that a libraries implemented in Rust are incorrect and slow but I do not understand what makes you believe so. I propose to implement a fast and correct math library in pure Rust.

I have said no such thing. There seems to be a misunderstanding of my concerns, so let me rephrase in a way that will hopefully be clearer.

The idea and proposal to implement a correct math library in rust is a fine and wonderful idea. I myself am a strong advocate for rust within the company that employs me, which is why I've recently integrated several small changes to support one of the platforms that I work on.

However, as a distribution maintainer, I can say with confidence that libm and related libraries (such as compiler-rt) often either heavily depend upon the compilers they were originally written for to produce specific optimisations, or have hand-crafted assembly. The compiler that rust uses, LLVM, is not yet as mature as gcc or other compilers when it comes to code optimisations, particularly on what some might consider more "exotic" or "niche" platforms. Likewise, gcc is not as correct or optimal at code generation as the native compilers sometimes provided with these platforms, although it's usually better than LLVM in my experience.

So then, as a distribution maintainer, it remains important to me that projects such as rust, while they are still maturing or expanding their support for platforms, provide a way for distribution maintainers to make appropriate choices for their platforms based upon platform requirements and other constraints.

As such, I am merely suggesting is that if the rust community chooses to pursue a version of libm written in rust, they do so with the consideration that some platforms on which LLVM is not as well optimised would be at a significant disadvantage if they were not able to use the native, equivalent library instead.

As just one such example of the difficulties distribution maintainers face, consider a recent bug report where the choice of compiler-rt may have affected platform performance.

Was this page helpful?
0 / 5 - 0 ratings