技术库 > linux

内存栅栏

技术库:tec.5lulu.com

1 什么是内存栅栏?

from:tec.5lulu.com

内存栅栏(Memory Barriers),是让一个CPU处理单元中的内存状态对其它处理单元可见的一项技术。

内存栅栏提供了两个功能

  • 确保从另一个CPU来看栅栏的两边的所有指令都是正确的程序顺序,而保持程序顺序的外部可见性;
  • 实现内存数据可见性,确保内存数据会同步到CPU缓存子系统。

2 为什么需要内存栅栏?

对主存的一次访问一般花费硬件的数百次时钟周期。为了减少这种操作,CPU通过使用Cache来达到高效获取数据的目的。然后Cache为了提高性能,会对指令进行重排序。
当重排序对最终的结果没有影响的时候,这种优化是有益的。但是当多线程共享数据时,重排序将导致错误的结果。所以为了在共享变量的情况下依然可以使用指令重排序,产生了内存栅栏来保证程序的正确性。

3 内存栅栏是怎么实现的?

在底层,内存栅栏是一组指令,一般包括Store Barrier、Load Barrier和Full Barrier。

几乎所有的处理器至少支持一种粗粒度的屏障指令,通常被称为“栅栏(Fence)”,它保证在栅栏前初始化的load和store指令,能够严格有序的在栅栏后的load和store指令之前执行。

不同的CPU架构有不同的实现方式,以X86为例:

  • Store Barrier,强制所有在store屏障指令之前的store指令,都在该store屏障指令执行之前被执行,并把store缓冲区的数据都刷到主存
  • Load Barrier,强制所有在load屏障指令之后的load指令,都在该load屏障指令执行之后被执行,并且一直等到load缓冲区被该CPU读完才能执行之后的load指令。
  • Full Barrier,复合了load和store屏蔽指令。
    无论在何种处理器上,这几乎都是最耗时的操作之一(与原子指令差不多,甚至更消耗资源),所以大部分处理器还会支持更细粒度的屏障指令。

下图是CPU的Local Memory与主存的通信过程:
内存栅栏,by 5lulu.com

4 Java中内存栅栏的使用

Java内存模型中volatile变量在写操作之后会插入一个store屏障,在读操作之前会插入一个load屏障。一个类的final字段会在初始化后插入一个store屏障,来确保final字段在构造函数初始化完成并可被使用时可见。

5 内存栅栏对性能的影响

内存栅栏阻止了 CPU 很多隐式的内存延迟技术的执行,因此是有性能损耗的,不过在上层看来这种损耗并不大。在合适的时候使用内存栅栏,仍然是一种高效的做法。

内存栅栏


标签: 内存 指令本文链接 http://tec.5lulu.com/detail/107msn4e62ap684fe.html

我来评分 :6.1
0

转载注明:转自5lulu技术库

本站遵循:署名-非商业性使用-禁止演绎 3.0 共享协议

www.5lulu.com

相关文章
1内存栅栏