2 个版本
使用旧的 Rust 2015
0.2.1 | 2017 年 7 月 11 日 |
---|---|
0.2.0 | 2017 年 1 月 6 日 |
#2241 在 数据结构
255KB
436 行
有界 SPSC 队列
此软件包提供了一种非常简单的有界、单生产者单消费者(SPSC)队列,用于 Rust。它提供了一种数据结构,允许两个线程以最小开销和有界语义进行单向通信。
与 sync_channel
相比,此队列提供了微小但一致的加速。 sync_channel
在底层使用无界链表数据结构,而 bounded_spsc_queue
是一个简单的环形缓冲区,具有单一的、连续的分配内存块。连续的内存块由于指针间接引用较少,因此允许更好的缓存预取,并且通常操作更简单,从而实现有界 SPSC 队列。
文档
示例
use std::thread;
use bounded_spsc_queue::{Producer, Consumer};
// Initialize a queue with capacity of 500 values
let (p, c) = bounded_spsc_queue::make(500);
// Spawn a new thread and move the Producer into it
thread::spawn(move|| {
for i in 0..100000 {
p.push(i);
}
});
// Back in the first thread, start pop'ing values off the queue
for i in 0..100000 {
let t = c.pop();
assert!(t == i);
}
半科学基准测试
在我的 MacBook Air(双核 1.7 GHz Intel Core i7)上,sync_channel
可以在 ~200ns 内执行单线程 send()/recv()
配对操作。
spsc
在 ~10ns 内执行相同的测试。
更真实但更难准确基准测试的是线程性能。此测试启动一个 "监听器" 线程,该线程试图尽可能快地清空队列。它必须间歇性地检查一个原子标志以确定测试是否结束,这不幸地会影响基准测试结果。为了减轻这种影响,监听器将仅在每 500 次迭代中检查一次。
在原始线程中,基准测试器尝试将数据推送到队列中。这是计时可能不稳定的地方:如果监听器清空队列不够快,生产者可能会在等待队列释放一个位置时停滞。此测试不应被视为延迟测试,而更应被视为吞吐量测试,因为它实际上是在测试生产者和消费者性能的结合。
sync_channel
在本测试中得分约为 ~6μs
而 spsc
得分约为 ~20ns
另一组基准测试关注于其逆过程(次要线程持续向队列中推送,而主线程从队列中取出数据)。时间测量非常相似。
换一种说法
- SPSC 每秒执行约 ~50m 次推送操作
- 同步通道每秒执行约 ~170k 次操作