]>
git.proxmox.com Git - rustc.git/blob - src/test/bench/shootout-spectralnorm.rs
1 // The Computer Language Benchmarks Game
2 // http://benchmarksgame.alioth.debian.org/
4 // contributed by the Rust Project Developers
6 // Copyright (c) 2012-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.
41 // no-pretty-expanded FIXME #15189
43 #![allow(non_snake_case)]
44 #![feature(unboxed_closures, iter_arith, core_simd, scoped)]
51 let mut args
= env
::args();
52 let answer
= spectralnorm(if env
::var_os("RUST_BENCH").is_some() {
54 } else if args
.len() < 2 {
57 args
.nth(1).unwrap().parse().unwrap()
59 println
!("{:.9}", answer
);
62 fn spectralnorm(n
: usize) -> f64 {
63 assert
!(n
% 2 == 0, "only even lengths are accepted");
64 let mut u
= vec
![1.0; n
];
65 let mut v
= u
.clone();
66 let mut tmp
= v
.clone();
68 mult_AtAv(&u
, &mut v
, &mut tmp
);
69 mult_AtAv(&v
, &mut u
, &mut tmp
);
71 (dot(&u
, &v
) / dot(&v
, &v
)).sqrt()
74 fn mult_AtAv(v
: &[f64], out
: &mut [f64], tmp
: &mut [f64]) {
79 fn mult_Av(v
: &[f64], out
: &mut [f64]) {
80 parallel(out
, |start
, out
| mult(v
, out
, start
, |i
, j
| A(i
, j
)));
83 fn mult_Atv(v
: &[f64], out
: &mut [f64]) {
84 parallel(out
, |start
, out
| mult(v
, out
, start
, |i
, j
| A(j
, i
)));
87 fn mult
<F
>(v
: &[f64], out
: &mut [f64], start
: usize, a
: F
)
88 where F
: Fn(usize, usize) -> f64 {
89 for (i
, slot
) in out
.iter_mut().enumerate().map(|(i
, s
)| (i
+ start
, s
)) {
90 let mut sum
= f64x2(0.0, 0.0);
91 for (j
, chunk
) in v
.chunks(2).enumerate().map(|(j
, s
)| (2 * j
, s
)) {
92 let top
= f64x2(chunk
[0], chunk
[1]);
93 let bot
= f64x2(a(i
, j
), a(i
, j
+ 1));
96 let f64x2(a
, b
) = sum
;
101 fn A(i
: usize, j
: usize) -> f64 {
102 ((i
+ j
) * (i
+ j
+ 1) / 2 + i
+ 1) as f64
105 fn dot(v
: &[f64], u
: &[f64]) -> f64 {
106 v
.iter().zip(u
).map(|(a
, b
)| *a
* *b
).sum()
110 // Executes a closure in parallel over the given mutable slice. The closure `f`
111 // is run in parallel and yielded the starting index within `v` as well as a
113 fn parallel
<'a
,T
, F
>(v
: &mut [T
], ref f
: F
)
114 where T
: Send
+ Sync
+ 'a
,
115 F
: Fn(usize, &mut [T
]) + Sync
+ 'a
{
116 // FIXME: pick a more appropriate parallel factor
118 let size
= v
.len() / parallelism
+ 1;
119 v
.chunks_mut(size
).enumerate().map(|(i
, chunk
)| {
120 thread
::scoped(move|| {
123 }).collect
::<Vec
<_
>>();