使用旧的 Rust 2015
0.6.4 |
|
---|---|
0.6.3 |
|
0.6.2 |
|
#11 在 #reclamation
16KB
178 行
Crossbeam-ArcCell
Crossbeam-ArcCell 是一个使用 crossbeam-epoch 进行内存回收的更新型 Arc 实现。它旨在在负载速度方面尽可能快和一致,但代价是写入可能不一致且可能非常慢。
此数据结构背后的思想是我们有一个原子指针,它始终指向有效数据。此数据应始终是原子指针解引用(和固定)。
当 ArcCell 需要更新时,旧值不能修改,因为它可能被其他线程使用。相反,现有数据必须克隆到新位置并修改。一旦准备好新值,就在原子指针上执行比较并交换,这样之后所有请求数据的线程都将接收到新更新的数据。最终,旧内存将被回收。
加载应该始终是常数时间,即使面对加载和更新竞争也是如此。
更新可能需要很长时间,传递给它的闭包可能运行多次。这是因为如果“旧”值在闭包完成之前更新,闭包可能会覆盖最新的数据,并且必须再次运行以传递新数据。此外,在这一点上执行旧 ArcCell 值的内存回收,除非使用 _no_reclaim()
方法。如果使用这些方法,请务必使用 reclaim()
方法以防止内存泄漏。
如果您想设置无论当前值如何都应设置的 ArcCell 数据,可以使用 set()
方法。此调用应该比更新快一些。
示例
extern crate crossbeam_arccell;
use crossbeam_arccell::ArcCell;
// Create a new ArcCell with a Vec of numbers
let arc = ArcCell::new(vec![1,2,3,4]);
// Read from the ArcCell
{
let data = arc.load();
println!("Current ArcCell value: {:?}", data);
}
// Update the ArcCell to add a new number
arc.update(|old| {
let mut new = old.clone();
new.push(5);
new
});
// Read the new data
{
let data = arc.load();
println!("Current ArcCell value: {:?}", data);
}
// Set the ArcCell value
let data = vec![9,8,7,6];
arc.set(data);
// Read the new data, again
{
let data = arc.load();
println!("Current ArcCell value: {:?}", data);
}
基准测试
请注意,这些基准测试在没有竞争的情况下存在。
在竞争情况下
- Crossbeam-ArcCell 的加载将始终是常数时间。
- 如果多个线程同时尝试写入,Crossbeam-ArcCell 的更新将减慢。
以下基准测试位于 benches/
目录下
// Crossbeam-ArcCell
test cb_arc_load ... bench: 9 ns/iter (+/- 0)
test cb_arc_update ... bench: 456 ns/iter (+/- 4)
test cb_arc_update_no_reclaim ... bench: 74 ns/iter (+/- 0)
test cb_arc_set ... bench: 444 ns/iter (+/- 6)
test cb_arc_set_no_reclaim ... bench: 64 ns/iter (+/- 0)
// Arc in stdlib
test arc_load ... bench: 11 ns/iter (+/- 0)
// RwLock in stdlib
test rwlock_load ... bench: 26 ns/iter (+/- 0)
test rwlock_update ... bench: 25 ns/iter (+/- 0)
// RwLock in parking_lot
test pl_rwlock_load ... bench: 16 ns/iter (+/- 1)
test pl_rwlock_update ... bench: 9 ns/iter (+/- 0)
许可
根据 MIT 许可证和 Apache 许可证(版本 2.0)的条款许可
有关详细信息,请参阅 LICENSE-MIT 和 LICENSE-APACHE
贡献
除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交用于包含在作品中的任何贡献,应按照上述方式双许可,不附加任何额外条款或条件。
依赖项
~450KB