]>
git.proxmox.com Git - rustc.git/blob - src/test/bench/shootout-nbody.rs
1 // The Computer Language Benchmarks Game
2 // http://benchmarksgame.alioth.debian.org/
4 // contributed by the Rust Project Developers
6 // Copyright (c) 2011-2014 The Rust Project Developers
8 // All rights reserved.
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions
14 // - Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
17 // - Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in
19 // the documentation and/or other materials provided with the
22 // - Neither the name of "The Computer Language Benchmarks Game" nor
23 // the name of "The Computer Language Shootout Benchmarks" nor the
24 // names of its contributors may be used to endorse or promote
25 // products derived from this software without specific prior
26 // written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 // OF THE POSSIBILITY OF SUCH DAMAGE.
45 const PI
: f64 = 3.141592653589793;
46 const SOLAR_MASS
: f64 = 4.0 * PI
* PI
;
47 const YEAR
: f64 = 365.24;
48 const N_BODIES
: usize = 5;
50 static BODIES
: [Planet
;N_BODIES
] = [
53 x
: 0.0, y
: 0.0, z
: 0.0,
54 vx
: 0.0, vy
: 0.0, vz
: 0.0,
59 x
: 4.84143144246472090e+00,
60 y
: -1.16032004402742839e+00,
61 z
: -1.03622044471123109e-01,
62 vx
: 1.66007664274403694e-03 * YEAR
,
63 vy
: 7.69901118419740425e-03 * YEAR
,
64 vz
: -6.90460016972063023e-05 * YEAR
,
65 mass
: 9.54791938424326609e-04 * SOLAR_MASS
,
69 x
: 8.34336671824457987e+00,
70 y
: 4.12479856412430479e+00,
71 z
: -4.03523417114321381e-01,
72 vx
: -2.76742510726862411e-03 * YEAR
,
73 vy
: 4.99852801234917238e-03 * YEAR
,
74 vz
: 2.30417297573763929e-05 * YEAR
,
75 mass
: 2.85885980666130812e-04 * SOLAR_MASS
,
79 x
: 1.28943695621391310e+01,
80 y
: -1.51111514016986312e+01,
81 z
: -2.23307578892655734e-01,
82 vx
: 2.96460137564761618e-03 * YEAR
,
83 vy
: 2.37847173959480950e-03 * YEAR
,
84 vz
: -2.96589568540237556e-05 * YEAR
,
85 mass
: 4.36624404335156298e-05 * SOLAR_MASS
,
89 x
: 1.53796971148509165e+01,
90 y
: -2.59193146099879641e+01,
91 z
: 1.79258772950371181e-01,
92 vx
: 2.68067772490389322e-03 * YEAR
,
93 vy
: 1.62824170038242295e-03 * YEAR
,
94 vz
: -9.51592254519715870e-05 * YEAR
,
95 mass
: 5.15138902046611451e-05 * SOLAR_MASS
,
99 #[derive(Copy, Clone)]
101 x
: f64, y
: f64, z
: f64,
102 vx
: f64, vy
: f64, vz
: f64,
106 fn advance(bodies
: &mut [Planet
;N_BODIES
], dt
: f64, steps
: isize) {
108 let mut b_slice
: &mut [_
] = bodies
;
110 let bi
= match shift_mut_ref(&mut b_slice
) {
114 for bj
in &mut *b_slice
{
115 let dx
= bi
.x
- bj
.x
;
116 let dy
= bi
.y
- bj
.y
;
117 let dz
= bi
.z
- bj
.z
;
119 let d2
= dx
* dx
+ dy
* dy
+ dz
* dz
;
120 let mag
= dt
/ (d2
* d2
.sqrt());
122 let massj_mag
= bj
.mass
* mag
;
123 bi
.vx
-= dx
* massj_mag
;
124 bi
.vy
-= dy
* massj_mag
;
125 bi
.vz
-= dz
* massj_mag
;
127 let massi_mag
= bi
.mass
* mag
;
128 bj
.vx
+= dx
* massi_mag
;
129 bj
.vy
+= dy
* massi_mag
;
130 bj
.vz
+= dz
* massi_mag
;
139 fn energy(bodies
: &[Planet
;N_BODIES
]) -> f64 {
141 let mut bodies
= bodies
.iter();
143 let bi
= match bodies
.next() {
147 e
+= (bi
.vx
* bi
.vx
+ bi
.vy
* bi
.vy
+ bi
.vz
* bi
.vz
) * bi
.mass
/ 2.0;
148 for bj
in bodies
.clone() {
149 let dx
= bi
.x
- bj
.x
;
150 let dy
= bi
.y
- bj
.y
;
151 let dz
= bi
.z
- bj
.z
;
152 let dist
= (dx
* dx
+ dy
* dy
+ dz
* dz
).sqrt();
153 e
-= bi
.mass
* bj
.mass
/ dist
;
159 fn offset_momentum(bodies
: &mut [Planet
;N_BODIES
]) {
164 px
+= bi
.vx
* bi
.mass
;
165 py
+= bi
.vy
* bi
.mass
;
166 pz
+= bi
.vz
* bi
.mass
;
168 let sun
= &mut bodies
[0];
169 sun
.vx
= - px
/ SOLAR_MASS
;
170 sun
.vy
= - py
/ SOLAR_MASS
;
171 sun
.vz
= - pz
/ SOLAR_MASS
;
175 let n
= if std
::env
::var_os("RUST_BENCH").is_some() {
178 std
::env
::args().nth(1)
179 .and_then(|arg
| arg
.parse().ok())
182 let mut bodies
= BODIES
;
184 offset_momentum(&mut bodies
);
185 println
!("{:.9}", energy(&bodies
));
187 advance(&mut bodies
, 0.01, n
);
189 println
!("{:.9}", energy(&bodies
));
192 /// Pop a mutable reference off the head of a slice, mutating the slice to no
193 /// longer contain the mutable reference. This is a safe operation because the
194 /// two mutable borrows are entirely disjoint.
195 fn shift_mut_ref
<'a
, T
>(r
: &mut &'a
mut [T
]) -> Option
<&'a
mut T
> {
199 if r
.len() == 0 { return None }
201 let mut raw
= r
.repr();
202 let ret
= raw
.data
as *mut T
;
203 raw
.data
= raw
.data
.offset(1);
205 *r
= mem
::transmute(raw
);