rust - Rust 中的安全并行高斯消元
问题描述
我正在尝试并行化高斯消除的实现。我知道像 rayon 这样的 crate 可能会使这更容易,但我的目标是使用基于 mpsc::channel 的实现,所以我选择使用 threadpool。
这是代码库的概述。有些功能是多余的,但是这段代码是从 C 移植过来的,所以我尝试维护结构。
传递过来的数据结构包含矩阵的大小(冗余)、矩阵、四个验证向量(用来判断正确性)和线程数:
pub struct Data {
pub nsize: usize,
pub matrix: Vec<Vec<f64>>,
pub b: Vec<f64>,
pub c: Vec<f64>,
pub v: Vec<f64>,
pub swap: Vec<u64>,
pub num_threads: usize,
}
顺序算法:
pub fn compute_gauss(data: &mut Data) {
for i in 0..data.nsize {
pivot(data, i);
let mut pivot_val;
for j in i + 1..data.nsize {
pivot_val = data.matrix[j][i];
data.matrix[j][i] = 0.0;
for k in i + 1..data.nsize {
data.matrix[j][k] -= pivot_val * data.matrix[i][k];
}
data.b[j] -= pivot_val * data.b[i];
}
}
}
该pivot(matrix,index)
函数改变数据中的矩阵
我当前的并行高斯实现:
pub fn compute_gauss_p(data: Data) -> Data {
let num_threads = data.num_threads;
let pool = ThreadPool::new(data.num_threads);
let nsize = data.nsize;
let sdata = Arc::new(data);
for i in 0..nsize {
pivot(&mut *sdata, i); //compile error, as Arc does not implement DerefMut
for n in 0..num_threads {
let sdatacpy = Arc::clone(&sdata);
pool.execute(move || {
do_calc(sdatacpy, i + n);
});
}
pool.join();
}
Arc::try_unwrap(sdata).unwrap()
}
fn do_calc(data: Arc<Data>, i: usize) { //cannot derefence mut from Arc
let mut pivot_val;
let num_threads = data.num_threads;
for j in (i + 1..data.matrix.len()).step_by(num_threads) {
pivot_val = data.matrix[j][i];
data.matrix[j][i] = 0.0;
for k in i + 1..data.matrix.len() {
data.matrix[j][k] -= pivot_val * data.matrix[i][k];
}
data.b[j] -= pivot_val * data.b[i];
}
}
我曾考虑过使用互斥锁来排除矩阵,但这会使工作顺序化。我的下一个想法是将矩阵视为互斥体的向量,每个向量都包含一行。这样我就可以分工。矩阵将是:
Vec<Mutex<Vec<f64>>>
但是,我想知道这是否是正确的路径。我想避免使用不安全的指针引用(我可以只使用我的 C 版本),同时继续使用具有 mpsc::channel 的范例(没有人造丝或其他不使用通道的库)。
解决方案
推荐阅读
- javascript - 更改滚动条颜色
- symfony - PHPUnit 测试中存储库的 Symfony 依赖注入或服务位置
- php - CSS 属性为何以及如何停止 PHP Header Location X?
- npm - 使用 npm 链接返回错误“未找到 - GET https://registry.npmjs.org/”
- javascript - Vue.js - 从回调函数访问数据变量
- javascript - React-spring - 动画 div 移除 onclick 功能
- html - 如何在 django 中消失 html 标签(安全标签无法正常工作)
- sql - 以 mm:ss 为单位的 BigQuery 时间戳
- android-studio - 如何启用编辑器捏放大 Android Studio?
- python - 如何强制文件路径相对于它所在的文件?