rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.09k stars 12.55k forks source link

Use sqrt intrinsic for floating point sqrt #5686

Closed brson closed 11 years ago

brson commented 11 years ago

sqrt is still using libc

huonw commented 11 years ago

I'm running tests on a patch that uses intrinsics for sqrt, sin, cos, exp, etc.

thestinger commented 11 years ago

@dbaupp: Nice! It would be awesome to have all of the useful LLVM intrinsics for integers/floats exposed.

huonw commented 11 years ago

Yay! 5x faster:

use core::float::sqrt;

fn main() {
    let mut sum: float = 0.0;
    for core::uint::range(0, 100000000) |i| {
        sum += sqrt(i as float);
    }
    io::println(fmt!("%f", sum));
}
# using cmath
$ rustc --opt-level=3 intrinsics-bench.rs  && time ./intrinsics-bench 
666666661666.567017

real    0m2.729s
user    0m2.712s
sys     0m0.008s

# using intrinsics
$ x86_64-unknown-linux-gnu/stage2/bin/rustc --opt-level=3 intrinsics-bench.rs  && time ./intrinsics-bench 
666666661666.567017

real    0m0.513s
user    0m0.500s
sys     0m0.008s
brson commented 11 years ago

@dbaupp mentioned on reddit that using some of these clobbers the stack canary. I hadn't considered that before and we need to think about how these are implemented. How many of the intrinsics that we are already using are just trotting all over the stack red zone? Perhaps LLVM's intrinsics don't emit the proper stack growth prologues.

huonw commented 11 years ago

(The very brief reddit thread, for future reference.)

Do I continue working on this? (i.e. open a pull request, since I've got the code basically organised.)

The (most) dangerous intrinsics seem to be sin, cos and exp, so I've left sin as libc and added sin_intr for the intrinsic etc.

brson commented 11 years ago

@dbaupp I'd like to know what assembly they generate. Do you have a test case that demonstrates all of them?

huonw commented 11 years ago

@brson: https://github.com/mozilla/rust/pull/5697

pcwalton commented 11 years ago

@huonw The necessary LLVM changes have been made.

However, I didn't realize that intrinsics can clobber the stack. I guess we need to write wrappers with the fixedstacksegment attribute for the problematic intrinsics (sin, cos) as well! This can be done entirely in the Rust compiler now, no need to patch LLVM.

huonw commented 11 years ago

@pcwalton Does fixed_stack_segment work on extern/intrinsic functions? i.e.

#[abi = "rust-intrinsic"]
pub extern "rust-intrinsic" {
   #[fixed_stack_segment]
   pub fn sinf32(x: f32) -> f32;
}
pcwalton commented 11 years ago

@huonw Extern functions automatically require fixed stack segments, if the #[fast_ffi] attribute is used. (Eventually this attribute will no longer be necessary.) However, I don't think that it will work for functions with the rust-intrinsic ABI, because I didn't realize that some intrinsic functions would need it.

huonw commented 11 years ago

@brson #5975 fixed this.

brson commented 11 years ago

Thanks @huonw!