mirror of https://github.com/xythrez/RustMP.git
Modified par_for to use split_iterator and ThreadPoolManager
This commit is contained in:
parent
5e7d6da4ec
commit
bb1391b8b2
|
@ -1,6 +1,5 @@
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rustmp::par_for;
|
use rustmp::par_for;
|
||||||
use rustmp::sysinfo::SystemObject;
|
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -23,13 +22,10 @@ fn main() {
|
||||||
|
|
||||||
par_for! {
|
par_for! {
|
||||||
for i in 1..10, capturing numbers {
|
for i in 1..10, capturing numbers {
|
||||||
// TODO: move this to parallel macro once tid design is finalized
|
|
||||||
SystemObject::get_instance().set_affinity(i as usize - 1)
|
|
||||||
.expect("Failed to bind thread to proc!");
|
|
||||||
|
|
||||||
std::thread::sleep(
|
//std::thread::sleep(
|
||||||
time::Duration::from_secs(
|
// time::Duration::from_secs(
|
||||||
rand::thread_rng().gen_range(1..10)));
|
// rand::thread_rng().gen_range(1..10)));
|
||||||
let mut lock = numbers.write();
|
let mut lock = numbers.write();
|
||||||
lock.push(Student::new(i));
|
lock.push(Student::new(i));
|
||||||
println!("Thread {} running!", i);
|
println!("Thread {} running!", i);
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
use rustmp::threadpool::{ThreadPoolManager, Job, as_static_job};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let tpm_mtx= ThreadPoolManager::get_instance_guard();
|
||||||
|
let tpm = tpm_mtx.lock().unwrap();
|
||||||
|
|
||||||
|
println!("Submitting jobs!");
|
||||||
|
let mut vector = Vec::new();
|
||||||
|
for i in 0..tpm.num_threads {
|
||||||
|
let cl = as_static_job(move || {println!("Hello from {}!", i)});
|
||||||
|
vector.push(cl);
|
||||||
|
}
|
||||||
|
tpm.exec(vector);
|
||||||
|
|
||||||
|
println!("Submitting more jobs with panic on tid=3!");
|
||||||
|
let mut vector2 = Vec::new();
|
||||||
|
for i in 0..tpm.num_threads {
|
||||||
|
let x = 9;
|
||||||
|
let cl = Arc::new(move || {
|
||||||
|
if x * i == 27 {
|
||||||
|
//panic!("Panic test");
|
||||||
|
}
|
||||||
|
}) as Job;
|
||||||
|
vector2.push(cl);
|
||||||
|
}
|
||||||
|
tpm.exec(vector2);
|
||||||
|
}
|
33
src/lib.rs
33
src/lib.rs
|
@ -41,20 +41,37 @@ impl<T> Capture<T> {
|
||||||
macro_rules! par_for {
|
macro_rules! par_for {
|
||||||
(for $name:ident in $iterator:expr, capturing $captured:ident $blk:block) => {
|
(for $name:ident in $iterator:expr, capturing $captured:ident $blk:block) => {
|
||||||
use rustmp::Capture;
|
use rustmp::Capture;
|
||||||
|
use rustmp::threadpool::{Job, ThreadPoolManager, as_static_job};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
let itr = $iterator;
|
let mut tasks = Vec::new();
|
||||||
let $captured = Capture::new($captured);
|
let $captured = Capture::new($captured);
|
||||||
let mut handles: Vec<thread::JoinHandle<()>> = vec![];
|
{
|
||||||
for $name in itr {
|
let tpm_mtx = ThreadPoolManager::get_instance_guard();
|
||||||
let $captured = $captured.clone();
|
let tpm = tpm_mtx.lock().unwrap();
|
||||||
handles.push(thread::spawn(move || $blk));
|
let iters = tpm.split_iterators($iterator, 1);
|
||||||
|
for iter in iters {
|
||||||
|
let $captured = $captured.clone();
|
||||||
|
tasks.push(as_static_job(move || {
|
||||||
|
for &$name in &iter
|
||||||
|
$blk
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
tpm.exec(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
for handle in handles {
|
//let itr = $iterator;
|
||||||
handle.join().expect("Thread paniced!");
|
//let $captured = Capture::new($captured);
|
||||||
}
|
//let mut handles: Vec<thread::JoinHandle<()>> = vec![];
|
||||||
|
//for $name in itr {
|
||||||
|
// let $captured = $captured.clone();
|
||||||
|
// handles.push(thread::spawn(move || $blk));
|
||||||
|
//}
|
||||||
|
|
||||||
|
//for handle in handles {
|
||||||
|
// handle.join().expect("Thread paniced!");
|
||||||
|
//}
|
||||||
|
|
||||||
let $captured = $captured.unwrap();
|
let $captured = $captured.unwrap();
|
||||||
};
|
};
|
||||||
|
|
|
@ -111,6 +111,34 @@ impl ThreadPoolManager {
|
||||||
// Used to return main thread from exec
|
// Used to return main thread from exec
|
||||||
self.task_barrier.wait();
|
self.task_barrier.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Splits an iterator into RMP_NUM_THREADS iterators, each with a step size of
|
||||||
|
/// block_size.
|
||||||
|
///
|
||||||
|
/// Returned iterators are stored in a Vec<Vec<S>>, but anything should work as
|
||||||
|
/// long as the default Rust for loop accepts it.
|
||||||
|
pub fn split_iterators<T, S>(&self, iter: T, block_size: usize) -> Vec<Vec<S>>
|
||||||
|
where
|
||||||
|
T: Iterator<Item=S>
|
||||||
|
{
|
||||||
|
let mut split = Vec::new();
|
||||||
|
split.reserve_exact(self.num_threads);
|
||||||
|
for _ in 0..self.num_threads {
|
||||||
|
split.push(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut index: usize = 0;
|
||||||
|
let mut block: usize = 0;
|
||||||
|
for element in iter {
|
||||||
|
split[index].push(element);
|
||||||
|
block += 1;
|
||||||
|
if block % block_size == 0 {
|
||||||
|
block = 0;
|
||||||
|
index = (index + 1) % self.num_threads;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
split
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper routine for threads in the ThreadPoolManager
|
/// Wrapper routine for threads in the ThreadPoolManager
|
||||||
|
|
Loading…
Reference in New Issue