diff --git a/src/main.rs b/src/main.rs index fe834c0..4cbe16f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ const SOLAR_MASS: f64 = 4. * PI * PI; const DAYS_PER_YEAR: f64 = 365.24; const BODIES_COUNT: usize = 5; -static mut solar_Bodies: [body; BODIES_COUNT] = [ +const STARTING_STATE: [body; BODIES_COUNT] = [ body { // Sun mass: SOLAR_MASS, @@ -181,7 +181,8 @@ fn output_Energy(bodies: &mut [body; BODIES_COUNT]) { // interactions between all the bodies, update each body's velocity based on // those interactions, and update each body's position by the distance it // travels in a timestep at it's updated velocity. -unsafe fn advance( +#[cfg(target_feature = "sse2")] +fn advance( bodies: &mut [body; BODIES_COUNT], position_Deltas: &mut [Interactions; 3], magnitudes: &mut Interactions, @@ -205,19 +206,21 @@ unsafe fn advance( // ROUNDED_INTERACTIONS_COUNT/2 iterations are done. for i in 0..ROUNDED_INTERACTIONS_COUNT / 2 { // Load position_Deltas of two bodies into position_Delta. - let mut position_Delta = [_mm_setzero_pd(); 3]; + let mut position_Delta = [unsafe { _mm_setzero_pd() }; 3]; for m in 0..3 { position_Delta[m] = position_Deltas[m].as_vectors()[i]; } - let distance_Squared: __m128d = _mm_add_pd( + let distance_Squared: __m128d = unsafe { _mm_add_pd( - _mm_mul_pd(position_Delta[0], position_Delta[0]), - _mm_mul_pd(position_Delta[1], position_Delta[1]), - ), - _mm_mul_pd(position_Delta[2], position_Delta[2]), - ); + _mm_add_pd( + _mm_mul_pd(position_Delta[0], position_Delta[0]), + _mm_mul_pd(position_Delta[1], position_Delta[1]), + ), + _mm_mul_pd(position_Delta[2], position_Delta[2]), + ) + }; // Doing square roots normally using double precision floating point // math can be quite time consuming so SSE's much faster single @@ -226,23 +229,25 @@ unsafe fn advance( // acceptable results so two iterations of the Newton–Raphson method are // done to improve precision further. let mut distance_Reciprocal: __m128d = - _mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(distance_Squared))); + unsafe { _mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(distance_Squared))) }; for _ in 0..2 { // Normally the last four multiplications in this equation would // have to be done sequentially but by placing the last // multiplication in parentheses, a compiler can then schedule that // multiplication earlier. - distance_Reciprocal = _mm_sub_pd( - _mm_mul_pd(distance_Reciprocal, _mm_set1_pd(1.5)), - _mm_mul_pd( + distance_Reciprocal = unsafe { + _mm_sub_pd( + _mm_mul_pd(distance_Reciprocal, _mm_set1_pd(1.5)), _mm_mul_pd( - _mm_mul_pd(_mm_set1_pd(0.5), distance_Squared), - distance_Reciprocal, + _mm_mul_pd( + _mm_mul_pd(_mm_set1_pd(0.5), distance_Squared), + distance_Reciprocal, + ), + _mm_mul_pd(distance_Reciprocal, distance_Reciprocal), ), - _mm_mul_pd(distance_Reciprocal, distance_Reciprocal), - ), - ); + ) + }; } // Calculate the magnitudes of force between the bodies. Typically this @@ -253,10 +258,12 @@ unsafe fn advance( // distance_Squared which was already calculated earlier. Additionally // this method is probably a little more accurate due to less rounding // as well. - magnitudes.as_vectors()[i] = _mm_mul_pd( - _mm_div_pd(_mm_set1_pd(0.01), distance_Squared), - distance_Reciprocal, - ); + magnitudes.as_vectors()[i] = unsafe { + _mm_mul_pd( + _mm_div_pd(_mm_set1_pd(0.01), distance_Squared), + distance_Reciprocal, + ) + }; } // Use the calculated magnitudes of force to update the velocities for all @@ -285,7 +292,7 @@ unsafe fn advance( } fn main() { - // These are new: + let mut solar_Bodies = STARTING_STATE; let mut position_Deltas: [Interactions; 3] = [Interactions { scalars: [0.; ROUNDED_INTERACTIONS_COUNT], }; 3]; @@ -293,13 +300,11 @@ fn main() { scalars: [0.; ROUNDED_INTERACTIONS_COUNT], }; - unsafe { - offset_Momentum(&mut solar_Bodies); - output_Energy(&mut solar_Bodies); - let c = std::env::args().nth(1).unwrap().parse().unwrap(); - for _ in 0..c { - advance(&mut solar_Bodies, &mut position_Deltas, &mut magnitudes); - } - output_Energy(&mut solar_Bodies); + offset_Momentum(&mut solar_Bodies); + output_Energy(&mut solar_Bodies); + let c = std::env::args().nth(1).unwrap().parse().unwrap(); + for _ in 0..c { + advance(&mut solar_Bodies, &mut position_Deltas, &mut magnitudes); } + output_Energy(&mut solar_Bodies); }