diff --git a/bench/programs_rust/hello-rust/src/main.rs b/bench/programs_rust/hello-rust/src/main.rs index 79fc530..5bdb78c 100644 --- a/bench/programs_rust/hello-rust/src/main.rs +++ b/bench/programs_rust/hello-rust/src/main.rs @@ -3,7 +3,7 @@ use core::{ arch::asm, - ops::{Add, Mul}, + ops::{Add, Mul, Sub}, }; use fpga_lib::{ @@ -18,11 +18,72 @@ pub const ITERATIONS: usize = 100; pub const ASPECT_RATIO: f32 = WIDTH as f32 / HEIGHT as f32; #[derive(Clone, Copy)] -struct Complex(Float, Float); +struct Complex(Q3x29, Q3x29); +#[derive(Clone, Copy)] +struct Q3x29(i32); + +impl From for Q3x29 +{ + fn from(x: f32) -> Q3x29 + { + const SCALE: f32 = 16.0; + const MAX_Q28_4: f32 = (u32::MAX as f32) / SCALE; + + let clamped = x.clamp(0.0, MAX_Q28_4); + let scaled = clamped * SCALE; + + Q3x29(scaled as i32) + } +} + +impl From for Q3x29 +{ + fn from(x: f64) -> Q3x29 + { + const SCALE: f64 = 16.0; + const MAX_Q28_4: f64 = (u32::MAX as f64) / SCALE; + + let clamped = x.clamp(0.0, MAX_Q28_4); + let scaled = clamped * SCALE; + + Q3x29(scaled as i32) + } +} + +impl Add for Q3x29 +{ + type Output = Q3x29; + + fn add(self, rhs: Self) -> Self::Output + { + Q3x29(self.0 + rhs.0) + } +} + +impl Sub for Q3x29 +{ + type Output = Q3x29; + + fn sub(self, rhs: Self) -> Self::Output + { + Q3x29(self.0 - rhs.0) + } +} + +impl Mul for Q3x29 +{ + type Output = Q3x29; + + fn mul(self, rhs: Self) -> Self::Output + { + let prod: i64 = self.0 as i64 * rhs.0 as i64; + Q3x29(((prod >> 28) & 0xFFFFFFFF) as i32) + } +} impl Complex { - pub fn sq_mag(&self) -> Float + pub fn sq_mag(&self) -> Q3x29 { self.0 * self.0 + self.1 * self.1 } @@ -63,47 +124,40 @@ pub extern "C" fn main() -> ! for i in 0..(ITERATIONS - 1) { let val = ((i as Float / ITERATIONS as Float) * 255.) as u8; - tab[i] = Color::from_rgb(val, val, val); + //tab[i] = Color::from_rgb(val, val, val); + tab[i] = Color(val); } tab }; - let width = 2.; + let zoom_int = 1; + let zoom = Q3x29::from(1. / zoom_int as f32); for x in 0..WIDTH { for y in 0..HEIGHT { + // -0.761574,-0.0847596) let pos = Complex( - map( - x as Float, - 0., - WIDTH as Float, - -width * ASPECT_RATIO * 0.5, - width * ASPECT_RATIO * 0.5, - ) - 0.5, - map(y as Float, 0., HEIGHT as Float, -width * 0.5, width * 0.5), + Q3x29((x as i32 - WIDTH as i32 / 2) * (0x1FFFFFFF / WIDTH as i32)) * zoom + - Q3x29::from(0.761574), + Q3x29((y as i32 - HEIGHT as i32 / 2) * (0x1FFFFFFF / WIDTH as i32)) * zoom + - Q3x29::from(0.0847596), ); let mut acc = pos; let mut iter = 0; - // Optimisations - let p = ((pos.0 - 0.25) * (pos.0 - 0.25)) + pos.1 * pos.1; - if (pos.0 < libm::sqrtf(p) - 2. * p + 0.25) - || (pos.0 + 1.) * (pos.0 + 1.) + pos.1 * pos.1 < 1. / 16. + for i in 0..ITERATIONS { - iter = ITERATIONS - 1; - } - else - { - for i in 0..ITERATIONS + //acc = acc * acc + pos; + acc = Complex( + pos.0 + acc.0 * acc.0 - acc.1 * acc.1, + pos.1 + Q3x29::from(2.) * acc.1 * acc.0, + ); + if acc.sq_mag().0 > Q3x29::from(3.8).0 { - acc = acc * acc + pos; - if acc.sq_mag() > 1. - { - iter = i; - break; - } + iter = i; + break; } }