Skip to content

Commit

Permalink
More unsafe indexing in inner loops and add some benchmarks.
Browse files Browse the repository at this point in the history
  • Loading branch information
sebcrozet committed Sep 13, 2013
1 parent 72395f3 commit 1a08262
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 26 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ nalgebra_lib_path=lib
nalgebra_doc_path=doc
all:
mkdir -p $(nalgebra_lib_path)
rust build src/lib.rs --out-dir $(nalgebra_lib_path) --opt-level 3
rust build src/lib.rs --out-dir $(nalgebra_lib_path) --opt-level 2

test:
mkdir -p $(nalgebra_lib_path)
rust test src/lib.rs
rm libtest~

bench:
rustc --test src/lib.rs --opt-level 2 -o bench~ && ./bench~ --bench
rm bench~

doc:
mkdir -p $(nalgebra_doc_path)
rust doc src/lib.rs --output-dir $(nalgebra_doc_path)
Expand All @@ -18,6 +22,7 @@ distcheck:
rm -rf $(tmp)
git clone --recursive . $(tmp)
make -C $(tmp)
make -C $(tmp) test
rm -rf $(tmp)

.PHONY:doc
Expand Down
164 changes: 164 additions & 0 deletions src/bench/mat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
use std::rand::random;
use extra::test::BenchHarness;
use mat::*;
use vec::*;

macro_rules! bench_mul_mat(
($bh: expr, $t: ty) => {
{
let a: $t = random();
let mut b: $t = random();

do $bh.iter {
do 1000.times {
b = a * b;
}
}
}
}
)

#[bench]
fn bench_mul_mat2(bh: &mut BenchHarness) {
bench_mul_mat!(bh, Mat2<f64>)
}

#[bench]
fn bench_mul_mat3(bh: &mut BenchHarness) {
bench_mul_mat!(bh, Mat3<f64>)
}

#[bench]
fn bench_mul_mat4(bh: &mut BenchHarness) {
bench_mul_mat!(bh, Mat4<f64>)
}

#[bench]
fn bench_mul_mat5(bh: &mut BenchHarness) {
bench_mul_mat!(bh, Mat5<f64>)
}

#[bench]
fn bench_mul_mat6(bh: &mut BenchHarness) {
bench_mul_mat!(bh, Mat6<f64>)
}

macro_rules! bench_mul_dmat(
($bh: expr, $nrows: expr, $ncols: expr) => {
{
let a: DMat<f64> = DMat::new_random($nrows, $ncols);
let mut b: DMat<f64> = DMat::new_random($nrows, $ncols);

do $bh.iter {
do 1000.times {
b = a * b;
}
}
}
}
)

#[bench]
fn bench_mul_dmat2(bh: &mut BenchHarness) {
bench_mul_dmat!(bh, 2, 2)
}

#[bench]
fn bench_mul_dmat3(bh: &mut BenchHarness) {
bench_mul_dmat!(bh, 3, 3)
}

#[bench]
fn bench_mul_dmat4(bh: &mut BenchHarness) {
bench_mul_dmat!(bh, 4, 4)
}

#[bench]
fn bench_mul_dmat5(bh: &mut BenchHarness) {
bench_mul_dmat!(bh, 5, 5)
}

#[bench]
fn bench_mul_dmat6(bh: &mut BenchHarness) {
bench_mul_dmat!(bh, 6, 6)
}

macro_rules! bench_mul_mat_vec(
($bh: expr, $tm: ty, $tv: ty) => {
{
let m : $tm = random();
let mut v : $tv = random();

do $bh.iter {
do 1000.times {
v = m.rmul(&v)
}
}
}
}
)

#[bench]
fn bench_mul_mat_vec2(bh: &mut BenchHarness) {
bench_mul_mat_vec!(bh, Mat2<f64>, Vec2<f64>)
}

#[bench]
fn bench_mul_mat_vec3(bh: &mut BenchHarness) {
bench_mul_mat_vec!(bh, Mat3<f64>, Vec3<f64>)
}

#[bench]
fn bench_mul_mat_vec4(bh: &mut BenchHarness) {
bench_mul_mat_vec!(bh, Mat4<f64>, Vec4<f64>)
}

#[bench]
fn bench_mul_mat_vec5(bh: &mut BenchHarness) {
bench_mul_mat_vec!(bh, Mat5<f64>, Vec5<f64>)
}

#[bench]
fn bench_mul_mat_vec6(bh: &mut BenchHarness) {
bench_mul_mat_vec!(bh, Mat6<f64>, Vec6<f64>)
}

macro_rules! bench_mul_dmat_dvec(
($bh: expr, $nrows: expr, $ncols: expr) => {
{
let m : DMat<f64> = DMat::new_random($nrows, $ncols);
let mut v : DVec<f64> = DVec::new_random($ncols);

do $bh.iter {
do 1000.times {
v = m.rmul(&v)
}
}
}
}
)

#[bench]
fn bench_mul_dmat_dvec2(bh: &mut BenchHarness) {
bench_mul_dmat_dvec!(bh, 2, 2)
}

#[bench]
fn bench_mul_dmat_dvec3(bh: &mut BenchHarness) {
bench_mul_dmat_dvec!(bh, 3, 3)
}

#[bench]
fn bench_mul_dmat_dvec4(bh: &mut BenchHarness) {
bench_mul_dmat_dvec!(bh, 4, 4)
}

#[bench]
fn bench_mul_dmat_dvec5(bh: &mut BenchHarness) {
bench_mul_dmat_dvec!(bh, 5, 5)
}

#[bench]
fn bench_mul_dmat_dvec6(bh: &mut BenchHarness) {
bench_mul_dmat_dvec!(bh, 6, 6)
}
44 changes: 44 additions & 0 deletions src/bench/vec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::rand::random;
use extra::test::BenchHarness;
use vec::*;

macro_rules! bench_dot_vec(
($bh: expr, $t: ty) => {
{
let a: $t = random();
let b: $t = random();
let mut d = 0.0;

do $bh.iter {
do 1000.times {
d = d + a.dot(&b);
}
}
}
}
)

#[bench]
fn bench_dot_vec2(bh: &mut BenchHarness) {
bench_dot_vec!(bh, Vec2<f64>)
}

#[bench]
fn bench_dot_vec3(bh: &mut BenchHarness) {
bench_dot_vec!(bh, Vec3<f64>)
}

#[bench]
fn bench_dot_vec4(bh: &mut BenchHarness) {
bench_dot_vec!(bh, Vec4<f64>)
}

#[bench]
fn bench_dot_vec5(bh: &mut BenchHarness) {
bench_dot_vec!(bh, Vec5<f64>)
}

#[bench]
fn bench_dot_vec6(bh: &mut BenchHarness) {
bench_dot_vec!(bh, Vec6<f64>)
}
7 changes: 6 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,10 @@ pub mod traits {
mod tests {
mod mat;
mod vec;
// mod bench;
}

#[cfg(test)]
mod bench {
mod mat;
mod vec;
}
6 changes: 6 additions & 0 deletions src/mat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ absolute_impl!(Mat1, m11)
one_impl!(Mat1, One::one)
iterable_impl!(Mat1, 1)
iterable_mut_impl!(Mat1, 1)
at_fast_impl!(Mat1, 1)
dim_impl!(Mat1, 1)
indexable_impl!(Mat1, 1)
mul_impl!(Mat1, 1)
Expand Down Expand Up @@ -113,6 +114,7 @@ iterable_impl!(Mat2, 2)
iterable_mut_impl!(Mat2, 2)
dim_impl!(Mat2, 2)
indexable_impl!(Mat2, 2)
at_fast_impl!(Mat2, 2)
mul_impl!(Mat2, 2)
rmul_impl!(Mat2, Vec2, 2)
lmul_impl!(Mat2, Vec2, 2)
Expand Down Expand Up @@ -169,6 +171,7 @@ iterable_impl!(Mat3, 3)
iterable_mut_impl!(Mat3, 3)
dim_impl!(Mat3, 3)
indexable_impl!(Mat3, 3)
at_fast_impl!(Mat3, 3)
mul_impl!(Mat3, 3)
rmul_impl!(Mat3, Vec3, 3)
lmul_impl!(Mat3, Vec3, 3)
Expand Down Expand Up @@ -254,6 +257,7 @@ iterable_impl!(Mat4, 4)
iterable_mut_impl!(Mat4, 4)
dim_impl!(Mat4, 4)
indexable_impl!(Mat4, 4)
at_fast_impl!(Mat4, 4)
mul_impl!(Mat4, 4)
rmul_impl!(Mat4, Vec4, 4)
lmul_impl!(Mat4, Vec4, 4)
Expand Down Expand Up @@ -352,6 +356,7 @@ iterable_impl!(Mat5, 5)
iterable_mut_impl!(Mat5, 5)
dim_impl!(Mat5, 5)
indexable_impl!(Mat5, 5)
at_fast_impl!(Mat5, 5)
mul_impl!(Mat5, 5)
rmul_impl!(Mat5, Vec5, 5)
lmul_impl!(Mat5, Vec5, 5)
Expand Down Expand Up @@ -461,6 +466,7 @@ iterable_impl!(Mat6, 6)
iterable_mut_impl!(Mat6, 6)
dim_impl!(Mat6, 6)
indexable_impl!(Mat6, 6)
at_fast_impl!(Mat6, 6)
mul_impl!(Mat6, 6)
rmul_impl!(Mat6, Vec6, 6)
lmul_impl!(Mat6, Vec6, 6)
Expand Down
40 changes: 32 additions & 8 deletions src/mat_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ macro_rules! mat_impl(
)
)

macro_rules! at_fast_impl(
($t: ident, $dim: expr) => (
impl<N: Clone> $t<N> {
#[inline]
unsafe fn at_fast(&self, (i, j): (uint, uint)) -> N {
(*cast::transmute::<&$t<N>, &[N, ..$dim * $dim]>(self)
.unsafe_ref(i * $dim + j)).clone()
}

#[inline]
unsafe fn set_fast(&mut self, (i, j): (uint, uint), val: N) {
(*cast::transmute::<&mut $t<N>, &mut [N, ..$dim * $dim]>(self)
.unsafe_mut_ref(i * $dim + j)) = val
}
}
)
)

macro_rules! mat_cast_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<Nin: NumCast + Clone, Nout: NumCast> MatCast<$t<Nout>> for $t<Nin> {
Expand Down Expand Up @@ -285,11 +303,13 @@ macro_rules! mul_impl(
for j in range(0u, $dim) {
let mut acc: N = Zero::zero();

for k in range(0u, $dim) {
acc = acc + self.at((i, k)) * other.at((k, j));
}
unsafe {
for k in range(0u, $dim) {
acc = acc + self.at_fast((i, k)) * other.at_fast((k, j));
}

res.set((i, j), acc);
res.set_fast((i, j), acc);
}
}
}

Expand All @@ -308,8 +328,10 @@ macro_rules! rmul_impl(

for i in range(0u, $dim) {
for j in range(0u, $dim) {
let val = res.at(i) + other.at(j) * self.at((i, j));
res.set(i, val)
unsafe {
let val = res.at_fast(i) + other.at_fast(j) * self.at_fast((i, j));
res.set_fast(i, val)
}
}
}

Expand All @@ -328,8 +350,10 @@ macro_rules! lmul_impl(

for i in range(0u, $dim) {
for j in range(0u, $dim) {
let val = res.at(i) + other.at(j) * self.at((j, i));
res.set(i, val)
unsafe {
let val = res.at_fast(i) + other.at_fast(j) * self.at_fast((j, i));
res.set_fast(i, val)
}
}
}

Expand Down
9 changes: 2 additions & 7 deletions src/tests/mat.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use std::num::{Real, One, abs};
use std::rand::random;
use std::cmp::ApproxEq;
use traits::inv::Inv;
use traits::rotation::Rotation;
use traits::indexable::Indexable;
use traits::transpose::Transpose;
use traits::norm::Norm;
use vec::{Vec1, Vec3};
use mat::{Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
use vec::*;
use mat::*;
use adaptors::rotmat::Rotmat;

macro_rules! test_inv_mat_impl(
Expand Down
11 changes: 2 additions & 9 deletions src/tests/vec.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
use std::num::{Zero, One};
use std::rand::{random};
use std::cmp::ApproxEq;
use vec::{Vec0, Vec1, Vec2, Vec3, Vec4, Vec5, Vec6};
use mat::Mat3;
use traits::basis::Basis;
use traits::cross::Cross;
use traits::dot::Dot;
use traits::norm::Norm;
use traits::iterable::{Iterable, IterableMut};
use traits::scalar_op::{ScalarAdd, ScalarSub};
use traits::outer::Outer;
use vec::*;
use mat::*;

macro_rules! test_iterator_impl(
($t: ty, $n: ty) => (
Expand Down
Loading

0 comments on commit 1a08262

Please sign in to comment.