#![feature(test)] #![allow(bad_style)] extern crate test; use test::Bencher; use lokacore::*; use randomize::*; pub fn make_a_pcg32_somehow() -> PCG32 { let mut gen_state: [u64; 2] = [0, 0]; getrandom::getrandom(bytes_of_mut(&mut gen_state)).unwrap(); PCG32::seed(gen_state[0], gen_state[1]) } #[repr(align(16))] #[derive(Clone, Copy)] struct Vec2Align16 { x: f32, y: f32, } impl Vec2Align16 { fn add(self, rhs: Self) -> Self { Self { x: self.x + rhs.x, y: self.y + rhs.y, } } fn mul(self, rhs: Self) -> Self { Self { x: self.x * rhs.x, y: self.y * rhs.y, } } } #[repr(align(16))] #[derive(Clone, Copy)] struct Vec3Align16 { x: f32, y: f32, z: f32, } impl Vec3Align16 { fn add(self, rhs: Self) -> Self { Self { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, } } fn mul(self, rhs: Self) -> Self { Self { x: self.x * rhs.x, y: self.y * rhs.y, z: self.z * rhs.z, } } } #[repr(align(16))] #[derive(Clone, Copy)] struct Vec4Align16 { x: f32, y: f32, z: f32, w: f32, } impl Vec4Align16 { fn add(self, rhs: Self) -> Self { Self { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, w: self.w + rhs.w, } } fn mul(self, rhs: Self) -> Self { Self { x: self.x * rhs.x, y: self.y * rhs.y, z: self.z * rhs.z, w: self.w * rhs.w, } } } #[bench] fn bench_Vec2Align16_add(b: &mut Bencher) { let gen = &mut make_a_pcg32_somehow(); let mut v1 = Vec2Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), }; let v2 = Vec2Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), }; b.iter(|| { for _ in 0..1000 { v1 = test::black_box(v1).add(test::black_box(v2)); } }); println!("{}", v1.x); } #[bench] fn bench_Vec3Align16_add(b: &mut Bencher) { let gen = &mut make_a_pcg32_somehow(); let mut v1 = Vec3Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), }; let v2 = Vec3Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), }; b.iter(|| { for _ in 0..1000 { v1 = test::black_box(v1).add(test::black_box(v2)); } }); println!("{}", v1.x); } #[bench] fn bench_Vec4Align16_add(b: &mut Bencher) { let gen = &mut make_a_pcg32_somehow(); let mut v1 = Vec4Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), w: f32::from_bits(gen.next_u32()), }; let v2 = Vec4Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), w: f32::from_bits(gen.next_u32()), }; b.iter(|| { for _ in 0..1000 { v1 = test::black_box(v1).add(test::black_box(v2)); } }); println!("{}", v1.x); } #[bench] fn bench_Vec2Align16_mul(b: &mut Bencher) { let gen = &mut make_a_pcg32_somehow(); let mut v1 = Vec2Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), }; let v2 = Vec2Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), }; b.iter(|| { for _ in 0..1000 { v1 = test::black_box(v1).mul(test::black_box(v2)); } }); println!("{}", v1.x); } #[bench] fn bench_Vec3Align16_mul(b: &mut Bencher) { let gen = &mut make_a_pcg32_somehow(); let mut v1 = Vec3Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), }; let v2 = Vec3Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), }; b.iter(|| { for _ in 0..1000 { v1 = test::black_box(v1).mul(test::black_box(v2)); } }); println!("{}", v1.x); } #[bench] fn bench_Vec4Align16_mul(b: &mut Bencher) { let gen = &mut make_a_pcg32_somehow(); let mut v1 = Vec4Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), w: f32::from_bits(gen.next_u32()), }; let v2 = Vec4Align16 { x: f32::from_bits(gen.next_u32()), y: f32::from_bits(gen.next_u32()), z: f32::from_bits(gen.next_u32()), w: f32::from_bits(gen.next_u32()), }; b.iter(|| { for _ in 0..1000 { v1 = test::black_box(v1).mul(test::black_box(v2)); } }); println!("{}", v1.x); }