auto merge of #6803 : Thiez/rust/native_fmax_fmin, r=brson

Calls to the libc versions of fmin and fmax were relatively slow (perhaps because they could not be inlined?). This pull request provides f32 and f64 with fmin and fmax written in Rust, and shows a significant speed increase on my system; I used https://github.com/thiez/rustray as my benchmark, with --opt-level 3 it brings the ray-tracing time down from 10.8 seconds to about 9.2, which seemed significant to me.

r?
This commit is contained in:
bors 2013-05-29 13:29:06 -07:00
commit 35655a0fb3
2 changed files with 19 additions and 4 deletions

View File

@ -86,8 +86,6 @@ delegate!(
fn erfc(n: c_float) -> c_float = c_float_utils::erfc,
fn exp_m1(n: c_float) -> c_float = c_float_utils::exp_m1,
fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub,
fn fmax(a: c_float, b: c_float) -> c_float = c_float_utils::fmax,
fn fmin(a: c_float, b: c_float) -> c_float = c_float_utils::fmin,
fn next_after(x: c_float, y: c_float) -> c_float = c_float_utils::next_after,
fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp,
fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot,
@ -147,6 +145,16 @@ pub fn ge(x: f32, y: f32) -> bool { return x >= y; }
#[inline(always)]
pub fn gt(x: f32, y: f32) -> bool { return x > y; }
#[inline(always)]
pub fn fmax(x: f32, y: f32) -> f32 {
if x >= y || y.is_NaN() { x } else { y }
}
#[inline(always)]
pub fn fmin(x: f32, y: f32) -> f32 {
if x <= y || y.is_NaN() { x } else { y }
}
// FIXME (#1999): replace the predicates below with llvm intrinsics or
// calls to the libmath macros in the rust runtime for performance.

View File

@ -87,8 +87,6 @@ delegate!(
fn erfc(n: c_double) -> c_double = c_double_utils::erfc,
fn exp_m1(n: c_double) -> c_double = c_double_utils::exp_m1,
fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub,
fn fmax(a: c_double, b: c_double) -> c_double = c_double_utils::fmax,
fn fmin(a: c_double, b: c_double) -> c_double = c_double_utils::fmin,
fn next_after(x: c_double, y: c_double) -> c_double = c_double_utils::next_after,
fn frexp(n: c_double, value: &mut c_int) -> c_double = c_double_utils::frexp,
fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot,
@ -172,6 +170,15 @@ pub fn ge(x: f64, y: f64) -> bool { return x >= y; }
#[inline(always)]
pub fn gt(x: f64, y: f64) -> bool { return x > y; }
#[inline(always)]
pub fn fmax(x: f64, y: f64) -> f64 {
if x >= y || y.is_NaN() { x } else { y }
}
#[inline(always)]
pub fn fmin(x: f64, y: f64) -> f64 {
if x <= y || y.is_NaN() { x } else { y }
}
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify