【问题标题】:How often does processor cache flush?处理器缓存多久刷新一次?
【发布时间】:2012-07-10 01:29:49
【问题描述】:

假设我有一个随意的单字节变量。我认为几乎所有系统上的单字节操作都是原子的,但如果不是,请告诉我。现在,假设一个线程更新了这个变量。我应该期待/准备多长时间才能让此更新出现在其他线程中?我知道我可以将更新放在互斥锁/锁/障碍周围,以确保它在任何地方都同步,但我对此很好奇。等待时间可能会有所不同,具体取决于其他线程是否位于不同的处理器/内核上,也可能取决于处理器类型。

我想知道这个是合乎逻辑的还是我误解了什么?

【问题讨论】:

  • 如果您正在编写任何依赖于这种行为的代码,您可能需要考虑一种不同的方法。今天的轻松记忆模型可能非常可怕。
  • 简短回答:在立即和从不之间。这取决于 CPU 架构、其他 CPU 正在做什么以及月相。有一些 cpu 架构,除非你明确刷新它,否则你不会看到它。此外,请注意将单个字节的写入视为“原子”,因为它们更有可能以字而不是字节为单位发生,并且根据 cpu 架构,您可能无法获得预期的结果。
  • 对于大多数架构而言,缓存不必刷新以使更改可见,因为 CPU 可以窥探到彼此的缓存 (en.wikipedia.org/wiki/Cache_coherence)。你应该更关心内存操作的重新排序。
  • @Suma,你说的内存操作重排序是什么意思,为什么这里可能会发生?

标签: c multithreading thread-safety pthreads


【解决方案1】:

只要调用同步原语/内存屏障(例如pthread_mutex_lock),内存就会同步。除此之外,除非您使用 C11 原子类型,否则不应假设任何同步。

【讨论】:

    【解决方案2】:

    在许多架构中,处理器不会刷新缓存,直到它必须 - 为一些更需要的数据让路。

    但是,如果线程共享内存空间,并且您只有一个内核,它们将能够“立即”从缓存中看到更新。如果它实际上是从 CPU 写入内存的。如果编译器决定将其保存在寄存器中,则可能不是这样,在这种情况下,您的线程都将拥有自己的“本地”和不正确的副本。

    正如其他人所说,这是一个有趣的问题 - 但同步的正确答案是使用适当的同步原语!

    【讨论】:

      【解决方案3】:

      在 MIPS 架构上,有一条同步指令用作跨内核的加载存储屏障,即发出同步之前的所有加载和存储都将在同步之后的任何加载和存储之前发生。不确定 x86 中是否有等效指令(假设这是您正在使用的架构)。

      【讨论】:

        猜你喜欢
        • 2014-07-07
        • 2018-05-10
        • 2018-08-22
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多