【问题标题】:Guaranteed CPU cache update after a certain time一定时间后保证 CPU 缓存更新
【发布时间】:2016-04-18 08:03:48
【问题描述】:

假设我有一个变量var 位于内存中的某个位置,并且任意数量的处理器/线程可以在任何给定时间读取和修改它。但可以保证在修改var 的处理器和读取var 的任何其他处理器之间至少经过n 秒。是否可以确定,如果以秒为单位的时间为n,则n 的值可以保证读取var 的处理器将读取更新后的值?

【问题讨论】:

  • 这个问题太笼统了,我无法想象它怎么可能得到有用的回答。您甚至没有指定语言,因此我们不知道适用哪些规则或“阅读”究竟意味着什么。
  • Waaaaay 广泛。什么类型的内存?哪种线程模型?什么语言?职业培训中心。

标签: multithreading multiprocessing cpu cpu-cache


【解决方案1】:

如果您真的担心Cache coherence,您应该通常是安全的1
但是,具体而言,您可能不是。

缓存一致性通常由硬件处理2,无需软件的帮助。 然而,这是非常特定于实现的:NUMA 可能不是缓存一致性,Compute Shader 可能需要特定的内置函数,IA32e 和 ARM 通常对程序员隐藏缓存一致性。

直接回答您的问题:不,您没有任何保证

关键是 缓存一致性 是您在集群和并行非统一架构中处理的问题。
虽然在这种情况下,编程模型本质上是多线程,但是这两个概念3 是分开的,真正应该让您烦恼的是如何正确处理多线程,特别是@ 987654324@和memory order

您的问题似乎提出了一个简单的案例,即读者在作者完成后很长时间才被执行。
如果此属性真的强制执行,则您不需要任何同步或内存屏障。但请注意,sleep 函数不符合有效执行条件。

如果您需要同步(并因此对内存访问进行排序),那么您需要使用特定于语言的构造,例如 C#Java 中的 volatile , atomicsCC++ 中或在 汇编 中的特定指令。
您可能还需要实施关键部分

如果您确实需要手动控制架构的缓存一致性,则必须检查感兴趣的规范(通常是数据表和正式论文),因为没有统一的方法来处理它,编译器应该提供一些内在的或者运行时应该提供一个库。

所以要在上面的直接答案中添加一些内容:不,你没有任何保证,但是当 usual CPU,在 usual 架构中,需要该数据,无论如何它将能够使用最新的数据。所以你不必担心那个方面。

请注意commonthat

这两个词的使用

1 例如,如果您使用 Intel/AMD/ARM CPU,请不要想关于缓存一致性。
2 CPU 本身、本地监视器、系统监视器或特定设备。
3 多线程和缓存一致性.

【讨论】:

  • 我已经在 2 天前发表了同样的评论 - If this property is really enforced you don't need any synchronization nor memory barrier. 不正确。有一些方法可以在线程模型之外强制执行排序,因此,仍然需要适当的线程模型 - 支持排序/同步。
  • @SergeyA mmm.. 你能澄清一下吗?强制线程 B 在线程 A 之后运行本身就是一种同步形式,所以我的声明“不需要任何同步”是一个小小的善意的谎言(意思是,不需要任何程序员感知同步)。这就是我使用“真的”这个词的原因。
  • 嗯,这里有不同的同步。为了清楚起见,让我们留在 Posix 线程模型中。 Posix 定义了它自己的同步协议(我们都知道它们),它根据定义强加了内存排序。但是还有其他方法可以在 Posix 模型之外同步您的线程 - 例如,您可以在 Linux 上为此使用 eventfd。虽然它们将提供执行顺序的同步,但不能保证它们提供内存顺序(虽然它们很可能只是由于其性质而这样做)。
【解决方案2】:

当缓存进入调度程序以查看是否有不同的任务要运行时,缓存往往会在操作系统滴答中断时被刷新。

但是,随着操作系统变得更加智能,例如无滴答 NoHz 以及 CPU 内核数量增加,这种可能性越来越小,您不应该指望它。

超级计算机集群可能不会在几分钟内一次切换任务,因为它们使用的自定义操作系统代码永远不会中断正在运行的作业。计算作业从 1 到 7 分配给一个核心,没有中断,所有其他工作都在核心 0 上运行。

【讨论】:

    【解决方案3】:

    您的问题中混杂了两个概念:软件同步和硬件一致性。 Margaret 已经谈到了硬件一致性,所以我不会在这里介绍。

    软件同步

    x86 保证如果在 64 位边界上对齐,四字访问将自动执行。但这保证了其他处理器不会读取部分结果(例如 [32bit New] 奇怪的混合)。它不能保证另一个处理器将看到新分配的值的硬时间期限。让另一个线程等待一段时间并不是一个优雅的解决方案,因为首先两个线程需要同步相同的启动时间。所以,如果你需要这样的保证,你需要条件变量来确保另一个线程应该等待。

    https://en.wikipedia.org/wiki/Monitor_(synchronization)

    总而言之,如果您需要排序效果,请使用条件变量,并使用锁/事务性内存等来保护比四字更长或不是 64 位对齐的变量。

    顺便说一句,如果您有兴趣,这里有一个关于缓存一致性的有用材料。

    http://www.cs.cmu.edu/afs/cs/academic/class/15418-s12/www/lectures/10_coherence.pdf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 2012-12-31
      • 2020-12-30
      • 2021-06-27
      相关资源
      最近更新 更多