#arc #memory #reclamation #atomically #load #speed #consistent

已删除 crossbeam-arccell

原子更新 Arc

使用旧的 Rust 2015

0.6.4 2018年8月7日
0.6.3 2018年8月7日
0.6.2 2018年8月7日

#11#reclamation

MIT/Apache

16KB
178

Crossbeam-ArcCell

crates.io crossbeam-arccell docs

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-MITLICENSE-APACHE

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交用于包含在作品中的任何贡献,应按照上述方式双许可,不附加任何额外条款或条件。

依赖项

~450KB