2014-09-13 90 views
12

某处,有一次我读了关于记忆栅栏(障碍)的内容。据说内存围栏导致几个CPU内核之间的高速缓存同步。内存防护是否会减慢所有CPU内核速度?

所以我的问题是:

  1. 怎样的OS(或CPU本身)知道哪些核心需要同步?

  2. 是否同步所有CPU内核的缓存?

  3. 如果答案(2)是“是”,并假设同步操作不便宜,不使用内存栅栏未使用我的应用内核慢下来?例如,如果我有一个在我的8核CPU上运行的单线程应用程序,它是否会减慢CPU的所有其他7个核心,因为一些缓存行必须与所有这些核心同步?

  4. 高于一无所知的问题和围栏的工作完全不同?

+1

操作系统不涉及这个,它是一个处理器细节。操作系统只是需要处理对围墙需求的另一大块软件,在其线程调度程序中必然如此。 – 2014-09-13 10:54:30

+0

栅栏实际上不同步缓存,它们同步程序流。 – Leeor 2014-09-17 14:07:27

回答

8
  1. 操作系统并不需要知道,每个CPU核心做什么它说:用的存储栅栏每个核心拥有之前或之后做一些操作,而这一切。核心不与“其他核心”同步,它是相对于自身同步内存访问。
  2. 在一个核心围栏并不意味着其他核心与它同步的,所以通常你将有两个(或更多)防护层:在一个作家,一个在阅读器。在一个内核上执行的防火墙不需要影响任何其他内核。当然,通常不能保证这一点,只是希望理智的体系结构不会不当地串行化多核执行。
+0

我明白了,谢谢。我很困惑那个'sync cache'的东西。思想内存栅栏意味着所有内核都会被通知某些缓存行必须失效。 – GreenScape 2014-09-13 12:54:29

1

如果您有八个内核,并且每个内核都在做不同的事情,那么这些内核不会访问相同的内存,并且不会在缓存行中拥有相同的内存。

如果核心#1使用的存储栅栏,但核心#1访问,那么其他核心将无法在所有的减缓没有其他内核访问的内存。但是,如果内核#1写入位置X,使用内存围栏,则内核#2尝试读取相同的位置X,内存围栏将确保内核#2丢弃位置X的值(如果它处于缓存,并从RAM中读取数据,获得与#1核心写入的数据相同的数据。这当然需要时间,但这就是那里的记忆栅栏。

(而不是从RAM读取,如果核心共享缓存部分,则数据将被从缓存中读取。)

5

一般来说,内存围栏用于订购当地操作。就拿这个伪汇编代码:

load A 
load B 

很多CPU的不保证B是后确实装,B可能是在被加载到缓存早前因其它一些内存负载的高速缓存行。如果您引入栅栏,

load A 
readFence 
load B 

您有保证B在A之后从内存加载。如果B在缓存中但比A旧,它将被重新加载。

设有专卖店的情况也是一样的相反。随着

store A 
store B 

某些CPU可能决定写B到存储他们写A.再次之前,可能需要在两个指令之间的篱笆执行操作的顺序。是否需要内存围栏总是取决于体系结构。


通常,使用内存栅栏成对:

  • 如果一个线程想要发布的对象,首要的是制造对象,然后将其写入指针之前执行写栅栏该对象进入公众所知的位置。

  • 想要接收对象的线程从公开的内存位置读取指针,然后执行读取栅栏以确保基于该指针的所有进一步读取实际上为发布线程预期的值。

如果缺少任何围栏,读取器可能会在初始化之前读取该对象的一个​​或多个数据成员的值。疯狂随之而来。

+0

您尚未解决问题。为什么这是最高的投票答案? – 2014-09-13 16:39:49

+0

嗯,我不能告诉你。但我的确是间接地解决了这个问题:对OP的误解似乎是记忆栅栏是某种全球性的操作。那就是为什么我详细说明了内存隔离的实际工作原理以及为什么他们纯粹是本地操作。我还展示了如何使用一对这些本地操作来实现全局数据一致性。没有直接的答案,这是真的,但我希望有用的。 – cmaster 2014-09-13 19:04:14