mirror of https://github.com/xythrez/RustMP.git
Merge branch 'shared_unsafe'
This commit is contained in:
commit
80853a1721
|
@ -0,0 +1,55 @@
|
||||||
|
use std::env;
|
||||||
|
use std::cmp::max;
|
||||||
|
use rand::random;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use rustmp::par_for;
|
||||||
|
|
||||||
|
fn gen_matrix(nsize: usize) -> Vec<Vec<f64>> {
|
||||||
|
let mut ret = Vec::with_capacity(nsize);
|
||||||
|
for _ in 0..nsize {
|
||||||
|
let mut row = Vec::with_capacity(nsize);
|
||||||
|
for _ in 0..nsize {
|
||||||
|
row.push((random::<f64>() - 0.5) * 255.0);
|
||||||
|
}
|
||||||
|
ret.push(row);
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_empty(nsize: usize) -> Vec<Vec<f64>> {
|
||||||
|
let mut ret = Vec::with_capacity(nsize);
|
||||||
|
let mut row = Vec::with_capacity(nsize);
|
||||||
|
for _ in 0..nsize {
|
||||||
|
row.push(0 as f64);
|
||||||
|
}
|
||||||
|
for _ in 0..nsize {
|
||||||
|
ret.push(row.clone());
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() != 2 {
|
||||||
|
eprintln!("Usage: {} <msize>", args[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let nsize = max(args[1].parse::<usize>().expect("Usage: matrix_mul <msize>"), 1);
|
||||||
|
let matrix = gen_matrix(nsize);
|
||||||
|
let mut result = gen_empty(nsize);
|
||||||
|
let timer = Instant::now();
|
||||||
|
par_for! {
|
||||||
|
for i in 0..nsize, shared_unsafe result, shared matrix, {
|
||||||
|
for j in 0..nsize {
|
||||||
|
let mut sum = 0.0;
|
||||||
|
for k in 0..nsize {
|
||||||
|
sum += matrix[i][k] * matrix[k][j];
|
||||||
|
}
|
||||||
|
result[i][j] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let interval = timer.elapsed();
|
||||||
|
println!("Elapsed time: {:?}", interval);
|
||||||
|
}
|
106
src/lib.rs
106
src/lib.rs
|
@ -2,6 +2,7 @@ pub mod threadpool;
|
||||||
|
|
||||||
mod sysinfo;
|
mod sysinfo;
|
||||||
|
|
||||||
|
use std::ops::{DerefMut, Deref};
|
||||||
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||||
|
|
||||||
pub use threadpool::{as_static_job, Job, ThreadPoolManager};
|
pub use threadpool::{as_static_job, Job, ThreadPoolManager};
|
||||||
|
@ -12,9 +13,9 @@ pub struct Capture<T> {
|
||||||
|
|
||||||
impl<T> Capture<T> {
|
impl<T> Capture<T> {
|
||||||
pub fn new(inner: T) -> Capture<T> {
|
pub fn new(inner: T) -> Capture<T> {
|
||||||
return Capture {
|
Capture {
|
||||||
value: Arc::new(RwLock::new(inner)),
|
value: Arc::new(RwLock::new(inner)),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone(&self) -> Capture<T> {
|
pub fn clone(&self) -> Capture<T> {
|
||||||
|
@ -39,6 +40,44 @@ impl<T> Capture<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct UnsafePtr<T> {
|
||||||
|
pub value: *mut T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> UnsafePtr<T> {
|
||||||
|
pub fn new(obj: &mut T) -> UnsafePtr<T> {
|
||||||
|
UnsafePtr {
|
||||||
|
value: obj as *mut T,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Copy for UnsafePtr<T> {}
|
||||||
|
|
||||||
|
impl<T> Clone for UnsafePtr<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
UnsafePtr { value: self.value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for UnsafePtr<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
unsafe { self.value.as_ref().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for UnsafePtr<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
unsafe { self.value.as_mut().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T> Send for UnsafePtr<T> {}
|
||||||
|
unsafe impl<T> Sync for UnsafePtr<T> {}
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! critical {
|
macro_rules! critical {
|
||||||
(read $($r:ident)+; readwrite $($w:ident)+; $($ops:tt)+) => {
|
(read $($r:ident)+; readwrite $($w:ident)+; $($ops:tt)+) => {
|
||||||
|
@ -85,22 +124,25 @@ macro_rules! __internal_par_for {
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction(),
|
reduction(),
|
||||||
$blk:block) => {
|
$blk:block) => {
|
||||||
let mut __rmp_tasks = Vec::new();
|
|
||||||
$(let $shared_mut = rustmp::Capture::new($shared_mut);)*
|
$(let $shared_mut = rustmp::Capture::new($shared_mut);)*
|
||||||
$(let $shared = std::sync::Arc::new($shared.clone());)*
|
|
||||||
{
|
{
|
||||||
|
let mut __rmp_tasks = Vec::new();
|
||||||
|
$(let $shared = std::sync::Arc::new($shared.clone());)*
|
||||||
|
$(let $shared_unsafe = rustmp::UnsafePtr::new(&mut $shared_unsafe);)*
|
||||||
let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard();
|
let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard();
|
||||||
let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap();
|
let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap();
|
||||||
let __rmp_iters = __rmp_tpm.split_iterators($iter, $size);
|
let __rmp_iters = __rmp_tpm.split_iterators($iter, $size);
|
||||||
for iter in __rmp_iters {
|
for iter in __rmp_iters {
|
||||||
$(let $shared_mut = $shared_mut.clone();)*
|
$(let $shared_mut = $shared_mut.clone();)*
|
||||||
$(let $shared = $shared.clone();)*
|
$(let $shared = $shared.clone();)*
|
||||||
// $(let $private = $private.clone();)*
|
$(let $private = $private.clone();)*
|
||||||
__rmp_tasks.push(rustmp::as_static_job(move || {
|
__rmp_tasks.push(rustmp::as_static_job(move || {
|
||||||
$(let mut $private = $private.clone();)*
|
$(let mut $private = $private.clone();)*
|
||||||
|
$(let mut $shared_unsafe = $shared_unsafe.clone();)*
|
||||||
for &$name in &iter
|
for &$name in &iter
|
||||||
$blk
|
$blk
|
||||||
}));
|
}));
|
||||||
|
@ -109,19 +151,22 @@ macro_rules! __internal_par_for {
|
||||||
}
|
}
|
||||||
$(let $shared_mut = $shared_mut.unwrap();)*
|
$(let $shared_mut = $shared_mut.unwrap();)*
|
||||||
};
|
};
|
||||||
|
|
||||||
// with reduction
|
// with reduction
|
||||||
(var_name($name:ident),
|
(var_name($name:ident),
|
||||||
iterator($iter:expr),
|
iterator($iter:expr),
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction($($red_name:ident, $red_op:tt)+),
|
reduction($($red_name:ident, $red_op:tt)+),
|
||||||
$blk:block) => {
|
$blk:block) => {
|
||||||
let mut __rmp_tasks = Vec::new();
|
|
||||||
$(let $shared_mut = rustmp::Capture::new($shared_mut);)*
|
$(let $shared_mut = rustmp::Capture::new($shared_mut);)*
|
||||||
$(let $shared = std::sync::Arc::new($shared.clone());)*
|
|
||||||
{
|
{
|
||||||
|
let mut __rmp_tasks = Vec::new();
|
||||||
|
$(let $shared = std::sync::Arc::new($shared.clone());)*
|
||||||
|
$(let $shared_unsafe = rustmp::UnsafePtr::new(&mut $shared_unsafe);)*
|
||||||
let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard();
|
let __rmp_tpm_mtx = rustmp::ThreadPoolManager::get_instance_guard();
|
||||||
let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap();
|
let __rmp_tpm = __rmp_tpm_mtx.lock().unwrap();
|
||||||
let __rmp_iters = __rmp_tpm.split_iterators($iter, $size);
|
let __rmp_iters = __rmp_tpm.split_iterators($iter, $size);
|
||||||
|
@ -131,11 +176,12 @@ macro_rules! __internal_par_for {
|
||||||
for iter in __rmp_iters {
|
for iter in __rmp_iters {
|
||||||
$(let $shared_mut = $shared_mut.clone();)*
|
$(let $shared_mut = $shared_mut.clone();)*
|
||||||
$(let $shared = $shared.clone();)*
|
$(let $shared = $shared.clone();)*
|
||||||
// $(let $private = $private.clone();)*
|
$(let $private = $private.clone();)*
|
||||||
let __rmp_red_vals = __rmp_red_vals.clone();
|
let __rmp_red_vals = __rmp_red_vals.clone();
|
||||||
$(let $red_name = $red_name.clone();)*
|
$(let $red_name = $red_name.clone();)*
|
||||||
__rmp_tasks.push(rustmp::as_static_job(move || {
|
__rmp_tasks.push(rustmp::as_static_job(move || {
|
||||||
$(let mut $private = $private.clone();)*
|
$(let mut $private = $private.clone();)*
|
||||||
|
$(let mut $shared_unsafe = $shared_unsafe.clone();)*
|
||||||
$(let mut $red_name = $red_name.clone();)*
|
$(let mut $red_name = $red_name.clone();)*
|
||||||
for &$name in &iter
|
for &$name in &iter
|
||||||
$blk
|
$blk
|
||||||
|
@ -147,17 +193,21 @@ macro_rules! __internal_par_for {
|
||||||
__rmp_tpm.exec(__rmp_tasks);
|
__rmp_tpm.exec(__rmp_tasks);
|
||||||
let mut __rmp_temp = __rmp_red_vals.read();
|
let mut __rmp_temp = __rmp_red_vals.read();
|
||||||
let mut __rmp_counter = 0;
|
let mut __rmp_counter = 0;
|
||||||
$($red_name = __rmp_temp[__rmp_counter].iter().fold($red_name, rustmp::__reduction_operation!($red_op));
|
$($red_name = __rmp_temp[__rmp_counter]
|
||||||
|
.iter()
|
||||||
|
.fold($red_name, rustmp::__reduction_operation!($red_op));
|
||||||
__rmp_counter += 1;)*
|
__rmp_counter += 1;)*
|
||||||
}
|
}
|
||||||
$(let $shared_mut = $shared_mut.unwrap();)*
|
$(let $shared_mut = $shared_mut.unwrap();)*
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse blocksize
|
// Parse blocksize
|
||||||
(var_name($name:ident),
|
(var_name($name:ident),
|
||||||
iterator($iter:expr),
|
iterator($iter:expr),
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction($($red_name:ident, $red_op:tt)*),
|
reduction($($red_name:ident, $red_op:tt)*),
|
||||||
blocksize $new_size:expr,
|
blocksize $new_size:expr,
|
||||||
|
@ -168,16 +218,19 @@ macro_rules! __internal_par_for {
|
||||||
blocksize($new_size),
|
blocksize($new_size),
|
||||||
shared_mut($($shared_mut)*),
|
shared_mut($($shared_mut)*),
|
||||||
shared($($shared)*),
|
shared($($shared)*),
|
||||||
|
shared_unsafe($($shared_unsafe)*),
|
||||||
private($($private)*),
|
private($($private)*),
|
||||||
reduction($($red_name, $red_op)*),
|
reduction($($red_name, $red_op)*),
|
||||||
$($rem)*)
|
$($rem)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse shared_mut
|
// Parse shared_mut
|
||||||
(var_name($name:ident),
|
(var_name($name:ident),
|
||||||
iterator($iter:expr),
|
iterator($iter:expr),
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction($($red_name:ident, $red_op:tt)*),
|
reduction($($red_name:ident, $red_op:tt)*),
|
||||||
shared_mut $($new_shared_mut:ident)*,
|
shared_mut $($new_shared_mut:ident)*,
|
||||||
|
@ -188,16 +241,19 @@ macro_rules! __internal_par_for {
|
||||||
blocksize($size),
|
blocksize($size),
|
||||||
shared_mut($($new_shared_mut)*),
|
shared_mut($($new_shared_mut)*),
|
||||||
shared($($shared)*),
|
shared($($shared)*),
|
||||||
|
shared_unsafe($($shared_unsafe)*),
|
||||||
private($($private)*),
|
private($($private)*),
|
||||||
reduction($($red_name, $red_op)*),
|
reduction($($red_name, $red_op)*),
|
||||||
$($rem)*)
|
$($rem)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse shared
|
// Parse shared
|
||||||
(var_name($name:ident),
|
(var_name($name:ident),
|
||||||
iterator($iter:expr),
|
iterator($iter:expr),
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction($($red_name:ident, $red_op:tt)*),
|
reduction($($red_name:ident, $red_op:tt)*),
|
||||||
shared $($new_name:ident)*,
|
shared $($new_name:ident)*,
|
||||||
|
@ -208,16 +264,42 @@ macro_rules! __internal_par_for {
|
||||||
blocksize($size),
|
blocksize($size),
|
||||||
shared_mut($($shared_mut)*),
|
shared_mut($($shared_mut)*),
|
||||||
shared($($new_name)*),
|
shared($($new_name)*),
|
||||||
|
shared_unsafe($($shared_unsafe)*),
|
||||||
private($($private)*),
|
private($($private)*),
|
||||||
reduction($($red_name, $red_op)*),
|
reduction($($red_name, $red_op)*),
|
||||||
$($rem)*)
|
$($rem)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Parse shared_unsafe
|
||||||
|
(var_name($name:ident),
|
||||||
|
iterator($iter:expr),
|
||||||
|
blocksize($size:expr),
|
||||||
|
shared_mut($($shared_mut:ident)*),
|
||||||
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
|
private($($private:ident)*),
|
||||||
|
reduction($($red_name:ident, $red_op:tt)*),
|
||||||
|
shared_unsafe $($new_shared_unsafe:ident)*,
|
||||||
|
$($rem:tt)+) => {
|
||||||
|
rustmp::__internal_par_for!(
|
||||||
|
var_name($name),
|
||||||
|
iterator($iter),
|
||||||
|
blocksize($size),
|
||||||
|
shared_mut($($shared_mut)*),
|
||||||
|
shared($($shared)*),
|
||||||
|
shared_unsafe($($new_shared_unsafe)*),
|
||||||
|
private($($private)*),
|
||||||
|
reduction($($red_name, $red_op)*),
|
||||||
|
$($rem)*)
|
||||||
|
};
|
||||||
|
|
||||||
// Parse private
|
// Parse private
|
||||||
(var_name($name:ident),
|
(var_name($name:ident),
|
||||||
iterator($iter:expr),
|
iterator($iter:expr),
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction($($red_name:ident, $red_op:tt)*),
|
reduction($($red_name:ident, $red_op:tt)*),
|
||||||
private $($new_private:ident)*,
|
private $($new_private:ident)*,
|
||||||
|
@ -228,16 +310,19 @@ macro_rules! __internal_par_for {
|
||||||
blocksize($size),
|
blocksize($size),
|
||||||
shared_mut($($shared_mut)*),
|
shared_mut($($shared_mut)*),
|
||||||
shared($($shared)*),
|
shared($($shared)*),
|
||||||
|
shared_unsafe($($shared_unsafe)*),
|
||||||
private($($new_private)*),
|
private($($new_private)*),
|
||||||
reduction($($red_name, $red_op)*),
|
reduction($($red_name, $red_op)*),
|
||||||
$($rem)*)
|
$($rem)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parse reduction
|
// Parse reduction
|
||||||
(var_name($name:ident),
|
(var_name($name:ident),
|
||||||
iterator($iter:expr),
|
iterator($iter:expr),
|
||||||
blocksize($size:expr),
|
blocksize($size:expr),
|
||||||
shared_mut($($shared_mut:ident)*),
|
shared_mut($($shared_mut:ident)*),
|
||||||
shared($($shared:ident)*),
|
shared($($shared:ident)*),
|
||||||
|
shared_unsafe($($shared_unsafe:ident)*),
|
||||||
private($($private:ident)*),
|
private($($private:ident)*),
|
||||||
reduction($($red_name:ident, $red_op:tt)*),
|
reduction($($red_name:ident, $red_op:tt)*),
|
||||||
reduction $($new_name:ident#$new_op:tt);*,
|
reduction $($new_name:ident#$new_op:tt);*,
|
||||||
|
@ -248,10 +333,12 @@ macro_rules! __internal_par_for {
|
||||||
blocksize($size),
|
blocksize($size),
|
||||||
shared_mut($($shared_mut)*),
|
shared_mut($($shared_mut)*),
|
||||||
shared($($shared)*),
|
shared($($shared)*),
|
||||||
|
shared_unsafe($($shared_unsafe)*),
|
||||||
private($($private)*),
|
private($($private)*),
|
||||||
reduction($($new_name, $new_op)*),
|
reduction($($new_name, $new_op)*),
|
||||||
$($rem)*)
|
$($rem)*)
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "parallel for" wrapper
|
/// "parallel for" wrapper
|
||||||
|
@ -267,6 +354,7 @@ macro_rules! par_for {
|
||||||
blocksize(1),
|
blocksize(1),
|
||||||
shared_mut(),
|
shared_mut(),
|
||||||
shared(),
|
shared(),
|
||||||
|
shared_unsafe(),
|
||||||
private(),
|
private(),
|
||||||
reduction(),
|
reduction(),
|
||||||
$($rem)*)
|
$($rem)*)
|
||||||
|
|
Loading…
Reference in New Issue