9个不稳定版本 (4个破坏性更新)
使用旧的Rust 2015
0.5.1 | 2018年2月11日 |
---|---|
0.4.2 | 2017年11月13日 |
0.4.1 | 2017年7月25日 |
0.3.0 | 2017年3月28日 |
#15 在 #spmc
每月下载量 98次
51KB
570 行
SPMC Buffer:多消费者使用的三缓冲
这是什么?
这是我之前关于三缓冲工作的扩展,它支持从多个消费者读取,以牺牲一些额外的内存和CPU开销为代价。您可能会发现它在以下类型的线程同步问题中很有用:
- 有一个生产者线程和几个消费者线程
- 生产者希望定期更新共享内存值
- 消费者希望随时访问生产者的最新更新
它目前的使用方式如下
// Create an SPMC buffer of any Clone type
use spmc_buffer::SPMCBuffer;
let buf = SPMCBuffer::new(2, 1.0);
// Split it into an input and output interface
let (mut buf_input, mut buf_output) = buf.split();
// Create as many extra output interfaces as needed
let mut buf_output2 = buf_output.clone();
// The producer can move a value into the buffer at any time
buf_input.write(4.2);
// A consumer can access the latest value from the producer at any time
let mut latest_value_ref = buf_output.read();
assert_eq!(*latest_value_ref, 4.2);
let latest_value_ref2 = buf_output2.read();
assert_eq!(*latest_value_ref2, 4.2);
给我详细说明!它与替代方案相比如何?
与三缓冲相比,SPMC缓冲...
- 支持多个消费者(这是关键!)
- 在单消费者情况下消耗更多的CPU时间和内存
- 对于写者来说,不总是无等待的。可以提供保证,但许多读者的内存成本相当高。
简而言之,SPMC缓冲是在以下场景中您所需要的:共享内存位置由单个写者频繁更新,由多个只想要最新版本的读者读取,并且您可以省出一些RAM。
- 如果您需要多个生产者,请另寻它处
- 如果您只需要一个消费者,请使用三缓冲
- 如果您无法忍受RAM开销或希望就地更新数据,请尝试Mutex(或可能是一个RWLock)
- 如果共享值很少更新(例如每秒一次),请尝试RCU
- 如果消费者必须获取每个更新,请尝试消息队列
我如何知道您的无锁代码是有效的?
当然是通过运行测试!但不幸的是,目前比我想的要困难。
首先,我们有顺序测试,这些测试非常彻底,但显然没有检查无锁/同步部分。您可以这样运行它们:
$ cargo test --release
然后我们有并发测试,其中我们启动并发读取器和写者线程,并检查读取者永远不会观察到不一致的缓冲区状态。这些测试更重要,但运行它们也更困难,因为必须首先检查一些假设:
- 测试主机必须至少有3个物理CPU核心才能测试所有可能的竞争条件
- 背景中没有其他代码应该消耗CPU。包括其他测试。
- 一些测试具有时序相关的行为,可能需要根据您的特定系统手动调整休眠时间。
考虑到这一点以及相对较长的运行时间(约10秒),这些测试默认情况下会被忽略。
最后,我们有基准测试,允许您测试代码在您的机器上的性能。由于 cargo bench 尚未进入稳定 Rust,这些基准测试伪装成测试,这使得它们运行起来有些不便。对此带来的不便,我表示歉意。
要运行并发测试和基准测试,请确保后台没有占用 CPU,并执行以下操作:
$ cargo test --release -- --ignored --test-threads=1
以下是解读基准测试结果指南
clean_read
测量数据未发生变化时的三缓冲区读取时间。它应该非常快(几个 CPU 时钟周期)。write
测量在没有人读取时写入三缓冲区所需的时间。write_and_dirty_read
在之前进行写入操作后立即进行顺序读取。为了获得脏读性能,从该结果中减去写入时间。写入和脏读应该花费可比较的时间。concurrent_write
测量在读者连续读取时的写入性能。预期性能会有明显下降:无锁技术可以帮助减少竞争,但并非万能。concurrent_read
测量在写入者连续写入时的读取性能。同样,预期会有显著的影响。
在我的笔记本电脑 CPU(Intel Core i7-4720HQ)上,典型结果如下:
- 写入:12 ns
- 干净读取:1.3 ns
- 脏读取:17 ns
- 并发写入:100 ns
- 并发读取:38 ns
许可证
本软件包在 MPLv2 许可证的条款下分发。有关详细信息,请参阅 LICENSE 文件。
也可以协商更宽松的许可证(Apache、MIT、BSD...),以换取财务捐助。如需详细信息,请联系 knights_of_ni AT gmx DOTCOM。
依赖关系
~140KB