Skip to content

Instantly share code, notes, and snippets.

@havchr
Created August 5, 2023 12:40
Show Gist options
  • Save havchr/590d1c1f6ba30833ff28230805b5eb7a to your computer and use it in GitHub Desktop.
Save havchr/590d1c1f6ba30833ff28230805b5eb7a to your computer and use it in GitHub Desktop.
I am trying to test the std::simd to measure performance , but I am new to this stuff, so I am wondering if I am doing things wrong?
#![feature(portable_simd)]
use std::simd::Simd;
use std::array;
use std::time::Duration;
use instant;
use rand::prelude::*;
const lanes : usize = 16;
fn main() {
println!("Hello, world!");
let (duration,simd_add,simd_prod) = do_simd_calculation(1_000_000);
println!("We spent {} seconds doing a million simds and simd_add = {}, and simd_prod = {}",duration.as_secs_f32(),simd_add,simd_prod);
let (duration,simd_add,simd_prod) = do_non_simd_calculation(1_000_000);
println!("We spent {} seconds doing a million non simds",duration.as_secs_f32());
}
fn do_non_simd_calculation(rep_count:usize)->(Duration,f32,f32){
let start = instant::Instant::now();
let mut total_sum = 0.0;
let mut total_prod = 0.0;
let mut rng = thread_rng();
for _ in 0..rep_count{
let (a_vec,b_vec) = create_random_float_arrays(lanes,&mut rng);
let a: [f32; lanes] = a_vec.try_into().unwrap();
let b: [f32; lanes] = b_vec.try_into().unwrap();
let sum:[f32;lanes] = array::from_fn(|i| a[i] + b[i]);
let prod:[f32;lanes] = array::from_fn(|i| a[i] * b[i]);
for val in sum{
total_sum+=val;
}
for val in prod{
total_prod+=val;
}
}
let now = instant::Instant::now();
(now-start,total_sum,total_prod)
}
fn do_simd_calculation(rep_count:usize)->(Duration,f32,f32){
let start = instant::Instant::now();
let mut total_sum = 0.0;
let mut total_prod = 0.0;
let mut rng = thread_rng();
for _ in 0..rep_count{
let (a_vec,b_vec) = create_random_float_arrays(lanes,&mut rng);
let a: [f32; lanes] = a_vec.try_into().unwrap();
let b: [f32; lanes] = b_vec.try_into().unwrap();
// `Simd<T, N>` implements `From<[T; N]>`
let (v, w) = (Simd::from(a), Simd::from(b));
let sum = v + w;
let product = v * w;
for val in sum.as_array(){
total_sum+=val;
}
for val in product.as_array(){
total_prod+=val;
}
}
let now = instant::Instant::now();
(now-start,total_sum,total_prod)
}
fn create_random_float_arrays(num_floats: usize,randomizer: &mut ThreadRng)-> (Vec<f32>,Vec<f32>)
{
let mut a_vec: Vec<f32> = Vec::new();
let mut b_vec: Vec<f32> = Vec::new();
for i in 0.. num_floats {
a_vec.push(randomizer.gen());
b_vec.push(randomizer.gen());
}
(a_vec,b_vec)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment