#barrier #rcu #memory-barrier #sys-membarrier

无 std membarrier

进程级内存屏障

5 个版本

使用旧的 Rust 2015

0.2.3 2023 年 3 月 21 日
0.2.2 2020 年 10 月 6 日
0.2.1 2018 年 11 月 14 日
0.2.0 2018 年 11 月 14 日
0.1.0 2018 年 3 月 28 日

#791 in 并发

Download history 36/week @ 2024-03-11 37/week @ 2024-03-18 11/week @ 2024-03-25 50/week @ 2024-04-01 30/week @ 2024-04-08 44/week @ 2024-04-15 40/week @ 2024-04-22 33/week @ 2024-04-29 28/week @ 2024-05-06 26/week @ 2024-05-13 45/week @ 2024-05-20 36/week @ 2024-05-27 36/week @ 2024-06-03 30/week @ 2024-06-10 46/week @ 2024-06-17 30/week @ 2024-06-24

每月 150 次下载

MIT/Apache

20KB
197

进程级内存屏障

Build Status License Cargo Documentation

内存屏障是现代松散内存并发中最强大的同步原语之一。在松散内存并发中,两个线程可能对底层内存系统有不同的观点,例如线程 T1 可能已经识别出在位置 X 的值 V,而 T2 完全不知道 X=V。这种差异是并发编程困难的主要原因之一。内存屏障通过这种方式同步线程,使得在内存屏障之后,线程对底层内存系统有相同的观点。

不幸的是,内存屏障并不便宜。通常,在现代计算机系统中,有一个专门的内存屏障指令,例如 x86 中的 MFENCE 和 ARM 中的 DMB SY,它们可能需要超过 100 个周期。内存屏障指令的使用可能在某些用例中可以忍受,例如少数线程的上下文切换,或同步在长时间运行过程中只发生一次的事件。然而,有时在快速路径上使用内存屏障是必要的,这会显著降低性能。

为了减少内存屏障的同步成本,Linux 和 Windows 提供了“进程级内存屏障”,这基本上是对进程中的每个线程执行内存屏障。尽管它比普通内存屏障指令慢,但有什么好处呢?以进程级内存屏障的代价,其他线程可以免除发出内存屏障指令!换句话说,通过使用进程级内存屏障,您可以在慢速路径的性能成本下优化快速路径。

对于进程级内存屏障,Linux 最近引入了 sys_membarrier() 系统调用,但已知在较老的 Linux 中,带有适当参数的 mprotect() 系统调用提供了进程级内存屏障语义。Windows 提供了 FlushProcessWriteBuffers() API。

用法

如下使用此 crate

extern crate membarrier;
use std::sync::atomic::{fence, Ordering};

membarrier::light();     // light-weight barrier
membarrier::heavy();     // heavy-weight barrier
fence(Ordering::SeqCst); // normal barrier

语义

正式来说,内存屏障有三种类型:轻量级屏障(membarrier::light())、重量级屏障(membarrier::heavy())和普通屏障(fence(Ordering::SeqCst))。在程序的执行过程中,所有内存屏障实例之间存在一个总顺序。如果线程A发出屏障X,线程B发出屏障Y,且X在Y之前,则在Y之后,A对X时刻底层内存系统的了解将传递给B,前提是

  • A或B的屏障是重量级的;或者
  • A和B的屏障都是普通的。

参考

有关更多信息,请参阅Linux man 页面的membarrierhttp://man7.org/linux/man-pages/man2/membarrier.2.html)。

依赖

~21–29MB
~383K SLoC