3 个不稳定版本
0.1.0 | 2024年5月22日 |
---|---|
0.0.3 | 2023年11月26日 |
0.0.1 | 2023年11月26日 |
#1097 在 并发
在 2 crates 中使用
35KB
379 行
paradis
paradis
目前处于早期、实验阶段。为了更容易地迭代整体设计,测试覆盖率故意较低。欢迎社区反馈!
paradis
通过提供更高层次的抽象,简化了需要访问类似于多维数组的结构的数据结构子集的索引的非平凡并行算法的实现。它通过提供更高层次的抽象来实现这一点。
- 为独立 记录 集合的无同步访问提供低级别、不安全抽象。
- 在低级别不安全基础上构建的高级抽象,允许许多并行访问模式以安全代码或以最小的不安全代码表达。
低级别抽象由非常轻量级的 paradis-core
crate 提供。鼓励库作者仅依赖此 crate 以暴露其数据结构供并行访问。
请查看 文档 以获取有关如何使用 paradis
的更多信息。
示例
此处提供的示例仅用于让您了解 API。请查看文档以获取更多上下文。
使用索引列表进行安全并行迭代
以下示例展示了如何使用 paradis
安全地在并行中迭代位于切片中任意索引处的可变元素。
use paradis::index::{IndexList, narrow_access_to_indices};
use paradis::rayon::create_par_iter;
use rayon::iter::ParallelIterator;
let mut data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let indices = vec![4, 7, 1].check_unique().expect("Indices are unique");
let access = narrow_access_to_indices(data.as_mut_slice(), &indices)
.expect("Indices are in bounds of the data structure");
create_par_iter(access).for_each(|x_i| *x_i = 0);
assert_eq!(data, vec![0, 0, 2, 3, 0, 5, 6, 0, 8, 9]);
结构化索引列表
对于某些问题,索引是 结构化 的。在这种情况下,我们可能能够避免运行时唯一性检查,而是通过结构化构造使用 索引组合子 来证明唯一性。下面的示例展示了结构化唯一性如何使我们能够修改矩阵的超对角线。
use nalgebra::dmatrix;
use paradis::index::{IndexList, narrow_access_to_indices};
use paradis::rayon::create_par_iter;
use rayon::iter::ParallelIterator;
// Access implementation omitted
use paradis_demo::DMatrixParAccessMut;
let mut matrix = dmatrix![1, 1, 1, 1, 1;
1, 1, 1, 1, 1;
1, 1, 1, 1, 1];
// Superdiagonal indices are [(0, 1), (1, 2), (2, 3)]
let superdiagonal_indices = (0 .. 3).index_zip(1 .. 4);
let access = DMatrixParAccessMut::from_matrix_mut(&mut matrix);
let superdiagonal_access = narrow_access_to_indices(access, &superdiagonal_indices)
.expect("Indices are in bounds");
create_par_iter(superdiagonal_access).for_each(|x_ij| *x_ij = 0);
assert_eq!(matrix,
dmatrix![1, 0, 1, 1, 1;
1, 1, 0, 1, 1;
1, 1, 1, 0, 1]);
低级别不安全并行访问
paradis
的高级功能建立在它的低级别 并行访问 抽象之上。以下示例展示了我们如何使用谨慎的无同步访问在不同的线程中修改切片的偶数和奇数部分。
use paradis_core::{BoundedParAccess, IntoParAccess};
use std::thread::scope;
let mut data = vec![0; 100];
let n = data.len();
let access = data.into_par_access();
scope(|s| {
s.spawn(|| {
// The first thread touches elements at even indices
for i in (0 .. n).step_by(2) {
unsafe { *access.get_unsync(i) = 1; }
}
});
s.spawn(|| {
// The second thread touches elements at odd indices
for i in (1 .. n).step_by(2) {
unsafe { *access.get_unsync(i) = 2; }
}
});
})
贡献
paradis
是开源的,欢迎贡献。您可以通过几种方式做出贡献
- 通过在您的应用中尝试
paradis
并在 论坛 中分享您的体验。 - 通过提交 问题,例如错误、改进想法或对设计的担忧。
- 通过修复错误、改进文档或作为拉取请求的一部分贡献新功能。请注意,并非所有新功能都将被接受。在投入大量时间进行新功能之前,请提交一个问题以查看该功能是否可能被接受。
请记住,paradis
并非专业开发。虽然我,@Andlon,有跟进问题和PR的打算,但生活中有时会有很多意外,有时会持续很长时间。
许可证
paradis
在您的选择下,根据MIT许可证或Apache许可证(版本2.0)的条款进行分发。有关详细信息,请参阅 LICENSE-APACHE
和 LICENSE-MIT
。
通过向此存储库贡献知识产权,您同意以相同的条款许可您的贡献。