rs-basic/members/tokryon/src/main.rs

96 lines
2.5 KiB
Rust

use rayon::prelude::*;
use std::io::prelude::*;
use tokio::time::Instant;
// if we make these larger, our computer can be used as a heater🔥
type Danum = u16; // you wont see any statuses for a long time with anything bigger than u16
const EXP: usize = 10; // FIXME: If this goes lower than 10, somehow the mpsc breaks sometimes
const CAP: usize = 1 << EXP;
const M: u128 = CAP as u128 * Danum::MAX as u128;
fn status(start: &Instant, info: (u128, usize), separate: usize) -> bool {
if info.0 < 1 {
return false;
}
let progress = info.0 as f64 / M as f64;
assert!(info.0 <= M);
let eq = info.0 == M;
println!(
r#"
done: {}
current threads: {}
progress: {}%
log_2(capacity): {}
log_2(sum): {}
cap: {}
sum: {}
sep: {}/{}
M: {}
took: {:?}
"#,
eq,
rayon::current_num_threads(),
progress * 100.0,
CAP.ilog2(),
info.0.ilog2(),
CAP,
info.0,
info.1,
separate,
M,
start.elapsed(),
);
eq
}
#[allow(clippy::uninit_vec)]
#[tokio::main]
async fn main() {
// Lets say that we want to add many numbers FAST
let mut range: Vec<Danum> = Vec::with_capacity(CAP);
// Initialize the values, probably zero
unsafe {
range.set_len(range.capacity());
}
let start = Instant::now();
let separate: usize = 1 << (EXP / 2);
// stops earlier sometimes
let (sender, recv) = std::sync::mpsc::channel();
rayon::spawn(move || {
for i in 0..separate {
range
.par_iter_mut()
.skip(i)
.step_by(separate)
.for_each(|num| {
for _ in 0..Danum::MAX {
*num += 1;
let _ = write!(std::io::Sink::default(), "{num}");
}
});
match sender.send((range.par_iter().map(|n| *n as u128).sum(), i + 1)) {
Ok(_) => (),
Err(err) => {
eprintln!("{err}");
break;
}
}
}
});
loop {
match recv.recv() {
Ok(tup) => {
if status(&start, tup, separate) {
break;
}
}
Err(err) => {
eprintln!("{err}");
break;
}
}
}
drop(recv);
}