Delete old files
This commit is contained in:
parent
d3bfcc194e
commit
a913be0373
3 changed files with 0 additions and 537 deletions
|
@ -1,224 +0,0 @@
|
||||||
/**
|
|
||||||
* Matrix multiplication performance test. For best results, compile with the optimise
|
|
||||||
* flag (-O). Surprisingly it seems mul_matrix_dot_product is faster than
|
|
||||||
* mul_matrix_expanded.
|
|
||||||
*
|
|
||||||
* Output:
|
|
||||||
*
|
|
||||||
* ~~~
|
|
||||||
* % rustc matrix_mul.rs -O
|
|
||||||
*
|
|
||||||
* % ./matrix_mul
|
|
||||||
* mul_matrix_expanded: 810 = 41
|
|
||||||
* mul_matrix_dot_product: 769 = 0
|
|
||||||
*
|
|
||||||
* % ./matrix_mul
|
|
||||||
* mul_matrix_expanded: 801 = 0
|
|
||||||
* mul_matrix_dot_product: 817 = 16
|
|
||||||
*
|
|
||||||
* % ./matrix_mul
|
|
||||||
* mul_matrix_expanded: 850 = 68
|
|
||||||
* mul_matrix_dot_product: 782 = 0
|
|
||||||
*
|
|
||||||
* % ./matrix_mul
|
|
||||||
* mul_matrix_expanded: 808 = 0
|
|
||||||
* mul_matrix_dot_product: 817 = 9
|
|
||||||
*
|
|
||||||
* % ./matrix_mul
|
|
||||||
* mul_matrix_expanded: 815 = 42
|
|
||||||
* mul_matrix_dot_product: 773 = 0
|
|
||||||
*
|
|
||||||
* % ./matrix_mul
|
|
||||||
* mul_matrix_expanded: 831 = 42
|
|
||||||
* mul_matrix_dot_product: 789 = 0
|
|
||||||
* ~~~
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern mod std;
|
|
||||||
use std::time::precise_time_ns;
|
|
||||||
use cast::transmute;
|
|
||||||
use cmp::Eq;
|
|
||||||
use vec::raw::buf_as_slice;
|
|
||||||
use ptr::to_unsafe_ptr;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let n_tests = 100000;
|
|
||||||
|
|
||||||
let a = Mat4::new(1f, 5f, 9f, 13f,
|
|
||||||
2f, 6f, 10f, 14f,
|
|
||||||
3f, 7f, 11f, 15f,
|
|
||||||
4f, 8f, 12f, 16f);
|
|
||||||
let b = Mat4::new(2f, 6f, 10f, 14f,
|
|
||||||
3f, 7f, 11f, 15f,
|
|
||||||
4f, 8f, 12f, 16f,
|
|
||||||
5f, 9f, 13f, 17f);
|
|
||||||
|
|
||||||
let expected = Mat4::new(100f, 228f, 356f, 484f,
|
|
||||||
110f, 254f, 398f, 542f,
|
|
||||||
120f, 280f, 440f, 600f,
|
|
||||||
130f, 306f, 482f, 658f);
|
|
||||||
|
|
||||||
let mul_matrix_expanded_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.mul_matrix_expanded(&b) == expected;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mul_matrix_dot_product_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.mul_matrix_dot_product(&b) == expected;
|
|
||||||
};
|
|
||||||
|
|
||||||
let min = [mul_matrix_expanded_avg, mul_matrix_dot_product_avg].min();
|
|
||||||
|
|
||||||
io::println(fmt!("mul_matrix_expanded: %d = %d", mul_matrix_expanded_avg as int, (mul_matrix_expanded_avg - min) as int));
|
|
||||||
io::println(fmt!("mul_matrix_dot_product: %d = %d", mul_matrix_dot_product_avg as int, (mul_matrix_dot_product_avg - min) as int));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector
|
|
||||||
|
|
||||||
pub struct Vec4 { x: float, y: float, z: float, w: float }
|
|
||||||
|
|
||||||
mod Vec4 {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new(x: float, y: float, z: float, w: float) -> Vec4 {
|
|
||||||
Vec4 { x: move x, y: move y, z: move z, w: move w }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vec4 {
|
|
||||||
#[inline(always)]
|
|
||||||
fn dot(other: &Vec4) -> float {
|
|
||||||
self[0] * other[0] +
|
|
||||||
self[1] * other[1] +
|
|
||||||
self[2] * other[2] +
|
|
||||||
self[3] * other[3]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl Vec4: Index<uint, float> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> float {
|
|
||||||
unsafe { do buf_as_slice(
|
|
||||||
transmute::<*Vec4, *float>(
|
|
||||||
to_unsafe_ptr(&self)), 4) |slice| { slice[*i] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl Vec4: Eq {
|
|
||||||
#[inline(always)]
|
|
||||||
fn eq(other: &Vec4) -> bool {
|
|
||||||
self[0] == other [0] &&
|
|
||||||
self[1] == other [1] &&
|
|
||||||
self[2] == other [2] &&
|
|
||||||
self[3] == other [3]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn ne(other: &Vec4) -> bool {
|
|
||||||
!(self == *other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matrix
|
|
||||||
|
|
||||||
pub struct Mat4 { x: Vec4, y: Vec4, z: Vec4, w: Vec4 }
|
|
||||||
|
|
||||||
mod Mat4 {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new(c0r0: float, c0r1: float, c0r2: float, c0r3: float,
|
|
||||||
c1r0: float, c1r1: float, c1r2: float, c1r3: float,
|
|
||||||
c2r0: float, c2r1: float, c2r2: float, c2r3: float,
|
|
||||||
c3r0: float, c3r1: float, c3r2: float, c3r3: float) -> Mat4 {
|
|
||||||
Mat4::from_cols(Vec4::new(move c0r0, move c0r1, move c0r2, move c0r3),
|
|
||||||
Vec4::new(move c1r0, move c1r1, move c1r2, move c1r3),
|
|
||||||
Vec4::new(move c2r0, move c2r1, move c2r2, move c2r3),
|
|
||||||
Vec4::new(move c3r0, move c3r1, move c3r2, move c3r3))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn from_cols(c0: Vec4, c1: Vec4, c2: Vec4, c3: Vec4) -> Mat4 {
|
|
||||||
Mat4 { x: move c0,
|
|
||||||
y: move c1,
|
|
||||||
z: move c2,
|
|
||||||
w: move c3 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mat4 {
|
|
||||||
#[inline(always)]
|
|
||||||
fn col(i: uint) -> Vec4 { self[i] }
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn row(i: uint) -> Vec4 {
|
|
||||||
Vec4::new(self[0][i],
|
|
||||||
self[1][i],
|
|
||||||
self[2][i],
|
|
||||||
self[3][i])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_matrix_expanded(other: &Mat4) -> Mat4 {
|
|
||||||
Mat4::new(self[0][0] * other[0][0] + self[1][0] * other[0][1] + self[2][0] * other[0][2] + self[3][0] * other[0][3],
|
|
||||||
self[0][1] * other[0][0] + self[1][1] * other[0][1] + self[2][1] * other[0][2] + self[3][1] * other[0][3],
|
|
||||||
self[0][2] * other[0][0] + self[1][2] * other[0][1] + self[2][2] * other[0][2] + self[3][2] * other[0][3],
|
|
||||||
self[0][3] * other[0][0] + self[1][3] * other[0][1] + self[2][3] * other[0][2] + self[3][3] * other[0][3],
|
|
||||||
|
|
||||||
self[0][0] * other[1][0] + self[1][0] * other[1][1] + self[2][0] * other[1][2] + self[3][0] * other[1][3],
|
|
||||||
self[0][1] * other[1][0] + self[1][1] * other[1][1] + self[2][1] * other[1][2] + self[3][1] * other[1][3],
|
|
||||||
self[0][2] * other[1][0] + self[1][2] * other[1][1] + self[2][2] * other[1][2] + self[3][2] * other[1][3],
|
|
||||||
self[0][3] * other[1][0] + self[1][3] * other[1][1] + self[2][3] * other[1][2] + self[3][3] * other[1][3],
|
|
||||||
|
|
||||||
self[0][0] * other[2][0] + self[1][0] * other[2][1] + self[2][0] * other[2][2] + self[3][0] * other[2][3],
|
|
||||||
self[0][1] * other[2][0] + self[1][1] * other[2][1] + self[2][1] * other[2][2] + self[3][1] * other[2][3],
|
|
||||||
self[0][2] * other[2][0] + self[1][2] * other[2][1] + self[2][2] * other[2][2] + self[3][2] * other[2][3],
|
|
||||||
self[0][3] * other[2][0] + self[1][3] * other[2][1] + self[2][3] * other[2][2] + self[3][3] * other[2][3],
|
|
||||||
|
|
||||||
self[0][0] * other[3][0] + self[1][0] * other[3][1] + self[2][0] * other[3][2] + self[3][0] * other[3][3],
|
|
||||||
self[0][1] * other[3][0] + self[1][1] * other[3][1] + self[2][1] * other[3][2] + self[3][1] * other[3][3],
|
|
||||||
self[0][2] * other[3][0] + self[1][2] * other[3][1] + self[2][2] * other[3][2] + self[3][2] * other[3][3],
|
|
||||||
self[0][3] * other[3][0] + self[1][3] * other[3][1] + self[2][3] * other[3][2] + self[3][3] * other[3][3])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mul_matrix_dot_product(other: &Mat4) -> Mat4 {
|
|
||||||
Mat4::new(self.row(0).dot(&other.col(0)), self.row(1).dot(&other.col(0)), self.row(2).dot(&other.col(0)), self.row(3).dot(&other.col(0)),
|
|
||||||
self.row(0).dot(&other.col(1)), self.row(1).dot(&other.col(1)), self.row(2).dot(&other.col(1)), self.row(3).dot(&other.col(1)),
|
|
||||||
self.row(0).dot(&other.col(2)), self.row(1).dot(&other.col(2)), self.row(2).dot(&other.col(2)), self.row(3).dot(&other.col(2)),
|
|
||||||
self.row(0).dot(&other.col(3)), self.row(1).dot(&other.col(3)), self.row(2).dot(&other.col(3)), self.row(3).dot(&other.col(3)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl Mat4: Index<uint, Vec4> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> Vec4 {
|
|
||||||
unsafe { do buf_as_slice(
|
|
||||||
transmute::<*Mat4, *Vec4>(
|
|
||||||
to_unsafe_ptr(&self)), 4) |slice| { slice[*i] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl Mat4: Eq {
|
|
||||||
#[inline(always)]
|
|
||||||
fn eq(other: &Mat4) -> bool {
|
|
||||||
self[0] == other [0] &&
|
|
||||||
self[1] == other [1] &&
|
|
||||||
self[2] == other [2] &&
|
|
||||||
self[3] == other [3]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn ne(other: &Mat4) -> bool {
|
|
||||||
!(self == *other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_avg_time_ns(n: uint, f: fn&()) -> u64 {
|
|
||||||
let mut total = 0;
|
|
||||||
for n.times {
|
|
||||||
let start_time = precise_time_ns();
|
|
||||||
|
|
||||||
f();
|
|
||||||
|
|
||||||
total += precise_time_ns() - start_time;
|
|
||||||
}
|
|
||||||
return total / (n as u64);
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/**
|
|
||||||
* Index operator performance test. For best results, compile with the optimise
|
|
||||||
* flag (-O). It seems like VecBufSlice is the fastest version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern mod std;
|
|
||||||
use std::time::precise_time_ns;
|
|
||||||
use cast::{reinterpret_cast, transmute};
|
|
||||||
use vec::raw::buf_as_slice;
|
|
||||||
use ptr::to_unsafe_ptr;
|
|
||||||
|
|
||||||
pub struct Vector { x: float, y: float, z: float, w: float }
|
|
||||||
|
|
||||||
pub struct VecMatch { x: float, y: float, z: float, w: float }
|
|
||||||
|
|
||||||
pub impl VecMatch: Index<uint, float> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> float {
|
|
||||||
match i {
|
|
||||||
0 => self.x,
|
|
||||||
1 => self.y,
|
|
||||||
2 => self.z,
|
|
||||||
3 => self.w,
|
|
||||||
_ => fail!(~"Vector index out of bounds.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VecReinterpret { x: float, y: float, z: float, w: float }
|
|
||||||
|
|
||||||
pub impl VecReinterpret: Index<uint, float> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> float unsafe {
|
|
||||||
(reinterpret_cast::<VecReinterpret, [float * 4]>(&self))[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VecTransmute { x: float, y: float, z: float, w: float }
|
|
||||||
|
|
||||||
pub impl VecTransmute: Index<uint, float> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> float unsafe {
|
|
||||||
(transmute::<VecTransmute, [float * 4]>(self))[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VecBufSlice { x: float, y: float, z: float, w: float }
|
|
||||||
|
|
||||||
pub impl VecBufSlice: Index<uint, float> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> float unsafe {
|
|
||||||
do vec::raw::buf_as_slice(
|
|
||||||
transmute::<*VecBufSlice, *float>(
|
|
||||||
to_unsafe_ptr(&self)), 4) |slice| { slice[*i] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let n_tests = 100000;
|
|
||||||
|
|
||||||
let v = Vector { x: 1f, y: 2f, z: 3f, w: 4f };
|
|
||||||
|
|
||||||
let vfield_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
// io::println(fmt!("[ %?, %?, %?, %? ]", v.x, v.y, v.z, v.w));
|
|
||||||
assert(v.x == 1f);
|
|
||||||
assert(v.y == 2f);
|
|
||||||
assert(v.z == 3f);
|
|
||||||
assert(v.w == 4f);
|
|
||||||
};
|
|
||||||
|
|
||||||
io::println(fmt!("Vector.x,y,z,w: [%d]", vfield_avg as int));
|
|
||||||
|
|
||||||
let vmatch = VecMatch { x: 1f, y: 2f, z: 3f, w: 4f };
|
|
||||||
|
|
||||||
let vindex_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert(vmatch[0] == 1f);
|
|
||||||
assert(vmatch[1] == 2f);
|
|
||||||
assert(vmatch[2] == 3f);
|
|
||||||
assert(vmatch[3] == 4f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let vreint = VecReinterpret { x: 1f, y: 2f, z: 3f, w: 4f };
|
|
||||||
|
|
||||||
let vreint_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert(vreint[0] == 1f);
|
|
||||||
assert(vreint[1] == 2f);
|
|
||||||
assert(vreint[2] == 3f);
|
|
||||||
assert(vreint[3] == 4f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let vtrans = VecTransmute { x: 1f, y: 2f, z: 3f, w: 4f };
|
|
||||||
|
|
||||||
let vtrans_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert(vtrans[0] == 1f);
|
|
||||||
assert(vtrans[1] == 2f);
|
|
||||||
assert(vtrans[2] == 3f);
|
|
||||||
assert(vtrans[3] == 4f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let vbufslice = VecBufSlice { x: 1f, y: 2f, z: 3f, w: 4f };
|
|
||||||
|
|
||||||
let vbufslice_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert(vbufslice[0] == 1f);
|
|
||||||
assert(vbufslice[1] == 2f);
|
|
||||||
assert(vbufslice[2] == 3f);
|
|
||||||
assert(vbufslice[3] == 4f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let min = [vfield_avg, vindex_avg, vreint_avg, vtrans_avg, vbufslice_avg].min();
|
|
||||||
|
|
||||||
io::println(fmt!("Vector.x,y,z,w: %d = %d", vfield_avg as int, (vfield_avg - min) as int));
|
|
||||||
io::println(fmt!("VecMatch[i]: %d = %d", vindex_avg as int, (vindex_avg - min) as int));
|
|
||||||
io::println(fmt!("VecReinterpret[i]: %d = %d", vreint_avg as int, (vreint_avg - min) as int));
|
|
||||||
io::println(fmt!("VecTransmute[i]: %d = %d", vtrans_avg as int, (vtrans_avg - min) as int));
|
|
||||||
io::println(fmt!("VecBufSlice[i]: %d = %d", vbufslice_avg as int, (vbufslice_avg - min) as int));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_avg_time_ns(n: uint, f: fn&()) -> u64 {
|
|
||||||
|
|
||||||
let mut total = 0;
|
|
||||||
for n.times {
|
|
||||||
let start_time = precise_time_ns();
|
|
||||||
|
|
||||||
f();
|
|
||||||
|
|
||||||
total += precise_time_ns() - start_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
return total / (n as u64);
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
/**
|
|
||||||
* Component-wise map and fold function speed tests. For best results, compile
|
|
||||||
* with the optimise flag (-O). These functions would allow for even more generic
|
|
||||||
* operations on dimensional data structures. Map seems to be faster than hand
|
|
||||||
* unrolling for add_t, but map2 for add_v is slower. A combination of map2 and
|
|
||||||
* foldl is faster for dot product.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern mod std;
|
|
||||||
use std::time::precise_time_ns;
|
|
||||||
use cast::transmute;
|
|
||||||
use vec::raw::buf_as_slice;
|
|
||||||
use ptr::to_unsafe_ptr;
|
|
||||||
use cmp::Eq;
|
|
||||||
use num::from_int;
|
|
||||||
|
|
||||||
pub struct Vec4<T> { x: T, y: T, z: T, w: T }
|
|
||||||
|
|
||||||
pub mod Vec4 {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn new<T>(x: T, y: T, z: T, w: T) -> Vec4<T> {
|
|
||||||
Vec4 { x: move x, y: move y, z: move z, w: move w }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl<T:Copy Num> Vec4<T> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn index(i: uint) -> T {
|
|
||||||
unsafe { do buf_as_slice(
|
|
||||||
transmute::<*Vec4<T>, *T>(
|
|
||||||
to_unsafe_ptr(&self)), 4) |slice| { slice[*i] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn map(f: fn&(a: &T) -> T) -> Vec4<T> {
|
|
||||||
Vec4::new(f(&self[0]),
|
|
||||||
f(&self[1]),
|
|
||||||
f(&self[2]),
|
|
||||||
f(&self[3]))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn map2(other: &Vec4<T>, f: fn&(a: &T, b: &T) -> T) -> Vec4<T> {
|
|
||||||
Vec4::new(f(&self[0], &other[0]),
|
|
||||||
f(&self[1], &other[1]),
|
|
||||||
f(&self[2], &other[2]),
|
|
||||||
f(&self[3], &other[3]))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foldl<U: Copy>(z: U, p: &fn(t: T, u: &U) -> U) -> U {
|
|
||||||
p(self[3], &p(self[2], &p(self[1], &p(self[0], &z))))
|
|
||||||
}
|
|
||||||
fn foldr<U: Copy>(z: U, p: &fn(t: &T, u: U) -> U) -> U {
|
|
||||||
p(&self[0], p(&self[1], p(&self[2], p(&self[3], z))))
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mul_t(value: T) -> Vec4<T> {
|
|
||||||
Vec4::new(self[0] * value,
|
|
||||||
self[1] * value,
|
|
||||||
self[2] * value,
|
|
||||||
self[3] * value)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn mul_t_map(value: T) -> Vec4<T> {
|
|
||||||
do self.map |a| { a * value }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn add_v(other: &Vec4<T>) -> Vec4<T> {
|
|
||||||
Vec4::new(self[0] + other[0],
|
|
||||||
self[1] + other[1],
|
|
||||||
self[2] + other[2],
|
|
||||||
self[3] + other[3])
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn add_v_map2(other: &Vec4<T>) -> Vec4<T> {
|
|
||||||
do self.map2(other) |a, b| { a + *b }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn dot(other: &Vec4<T>) -> T {
|
|
||||||
self[0] * other[0] +
|
|
||||||
self[1] * other[1] +
|
|
||||||
self[2] * other[2] +
|
|
||||||
self[3] * other[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn dot_foldl(other: &Vec4<T>) -> T {
|
|
||||||
self.map2(other, |a, b| { a * *b })
|
|
||||||
.foldl(from_int(0), |t, u| { t + *u })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl<T:Copy Num Eq> Vec4<T>: Eq {
|
|
||||||
#[inline(always)]
|
|
||||||
fn eq(other: &Vec4<T>) -> bool {
|
|
||||||
self[0] == other[0] &&
|
|
||||||
self[1] == other[1] &&
|
|
||||||
self[2] == other[2] &&
|
|
||||||
self[3] == other[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn ne(other: &Vec4<T>) -> bool {
|
|
||||||
!(self == *other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let n_tests = 10000;
|
|
||||||
|
|
||||||
// Map
|
|
||||||
|
|
||||||
let a = Vec4::new(1f, 2f, 3f, 4f);
|
|
||||||
let b = Vec4::new(5f, 6f, 7f, 8f);
|
|
||||||
|
|
||||||
let mul_t_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.mul_t(8f) == Vec4::new(8f, 16f, 24f, 32f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let mul_t_map_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.mul_t_map(8f) == Vec4::new(8f, 16f, 24f, 32f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let min = [mul_t_avg, mul_t_map_avg].min();
|
|
||||||
|
|
||||||
io::println(fmt!("mul_t: %d = %d", mul_t_avg as int, (mul_t_avg - min) as int));
|
|
||||||
io::println(fmt!("mul_t_map: %d = %d", mul_t_map_avg as int, (mul_t_map_avg - min) as int));
|
|
||||||
|
|
||||||
// Zip
|
|
||||||
|
|
||||||
let add_v_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.add_v(&b) == Vec4::new( 6f, 8f, 10f, 12f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let add_v_map2_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.add_v_map2(&b) == Vec4::new( 6f, 8f, 10f, 12f);
|
|
||||||
};
|
|
||||||
|
|
||||||
let min = [add_v_avg, add_v_map2_avg].min();
|
|
||||||
|
|
||||||
io::println(fmt!("add_v: %d = %d", add_v_avg as int, (add_v_avg - min) as int));
|
|
||||||
io::println(fmt!("add_v_map2: %d = %d", add_v_map2_avg as int, (add_v_map2_avg - min) as int));
|
|
||||||
|
|
||||||
// Dot
|
|
||||||
|
|
||||||
let dot_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.dot(&b) == 70f;
|
|
||||||
};
|
|
||||||
|
|
||||||
let dot_foldl_avg = do test_avg_time_ns(n_tests) {
|
|
||||||
assert a.dot_foldl(&b) == 70f;
|
|
||||||
};
|
|
||||||
|
|
||||||
let min = [dot_avg, dot_foldl_avg].min();
|
|
||||||
|
|
||||||
io::println(fmt!("dot: %d = %d", dot_avg as int, (dot_avg - min) as int));
|
|
||||||
io::println(fmt!("dot_foldl: %d = %d", dot_foldl_avg as int, (dot_foldl_avg - min) as int));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_avg_time_ns(n: uint, f: fn&()) -> u64 {
|
|
||||||
|
|
||||||
let mut total = 0;
|
|
||||||
for n.times {
|
|
||||||
let start_time = precise_time_ns();
|
|
||||||
|
|
||||||
f();
|
|
||||||
|
|
||||||
total += precise_time_ns() - start_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
return total / (n as u64);
|
|
||||||
}
|
|
Loading…
Reference in a new issue