一定时间后保证 CPU 缓存更新
Guaranteed CPU cache update after a certain time
假设我有一个变量 var
位于内存中的某处,并且任意数量的 processors/threads 可以在任何给定时间读取和修改它。但可以保证在处理器修改 var
和任何其他处理器读取 var
之间至少经过 n
秒。是否可以确定,如果以秒为单位的时间为 n
,则 n
的值可以保证处理器读取 var
将读取更新后的值?
如果你确实担心Cache coherence你应该通常注意安全1.
但是,具体来说,您可能不是。
缓存一致性通常由硬件处理2,无需借助软件。
然而,这是非常具体的实现:NUMA may be non cache-coherent, a Compute Shader 可能需要特定的内置函数,IA32e 和 ARM 通常对程序员隐藏缓存一致性。
直接回答你的问题:不,你没有任何保证。
重点是 缓存一致性 是您在集群和并行非统一架构中处理的问题。
虽然在这种情况下,编程模型本质上是 多线程 ,但这两个概念 3 是分开的,真正应该困扰您的是如何正确处理多线程,特别是 synchronization and memory order.
你的问题似乎暗示了一个简单的案例,即读者在作者完成后很长时间内被处决。
如果此 属性 是 确实 强制执行,则您不需要任何同步或内存屏障。但是请注意,sleep
函数不符合有效强制执行的条件。
如果您需要同步(从而对内存访问进行排序),那么您需要使用特定于语言的结构,例如 C# 中的 volatile
和 Java、C和C++中的atomics
或[=中的具体说明36=]程序集.
您可能还需要实施关键部分。
如果你真的需要为你的架构手动控制缓存一致性,那么你必须检查感兴趣的规范(通常是数据表和正式论文),因为没有统一的方法来处理它,编译器应该提供一些内在的或运行时应该提供一个库。
所以在上面的直接答案中添加一些东西:不,你没有任何保证,但是当通常 CPU,在普通架构,需要那个资料,反正用最新的就可以了。所以你不用担心那个方面。
请注意 common 和 that 的用法
1 例如,如果您使用 Intel/AMD/ARM CPU,缓存一致性就别想了
2 CPU 本身、本地监视器、系统监视器或特定设备。
3 多线程和缓存一致性。
当进入调度程序以查看是否有与 运行 不同的任务时,缓存往往会在操作系统节拍中断时被刷新。
但是,随着操作系统变得越来越智能,例如 tickless NoHz 以及 CPU 核心数量增加,这种可能性越来越小,您不应该指望它。
超级计算机集群可能不会在几分钟内一次切换任务,因为它们使用的是定制的操作系统代码,不会中断 运行ning 作业,永远不会。计算作业被分配给核心 1-7,没有中断,所有其他工作 运行s 在核心 0 上。
你的问题中混入了两个概念:软件同步和硬件一致性。 Margaret 已经谈到了硬件一致性,所以我不会在这里介绍它。
软件同步
x86 保证如果在 64 位边界上对齐,四字访问将自动执行。但这保证了其他处理器不会读取部分结果(例如 [32bit New]<32bit Old> weird mixture)。它不保证另一个处理器可以看到新分配的值的硬时间期限。让另一个线程等待一段时间并不是一个很好的解决方案,因为首先两个线程需要同步相同的开始时间。所以,如果你需要这样的保证,你需要条件变量来确保另一个线程应该等待。
https://en.wikipedia.org/wiki/Monitor_(synchronization)
总之,如果需要顺序效果,使用条件变量,使用locks/transactional内存等保护变量超过四字或非64位对齐。
顺便说一句,如果您有兴趣,这里有一个有用的 material 缓存一致性。
http://www.cs.cmu.edu/afs/cs/academic/class/15418-s12/www/lectures/10_coherence.pdf
假设我有一个变量 var
位于内存中的某处,并且任意数量的 processors/threads 可以在任何给定时间读取和修改它。但可以保证在处理器修改 var
和任何其他处理器读取 var
之间至少经过 n
秒。是否可以确定,如果以秒为单位的时间为 n
,则 n
的值可以保证处理器读取 var
将读取更新后的值?
如果你确实担心Cache coherence你应该通常注意安全1.
但是,具体来说,您可能不是。
缓存一致性通常由硬件处理2,无需借助软件。 然而,这是非常具体的实现:NUMA may be non cache-coherent, a Compute Shader 可能需要特定的内置函数,IA32e 和 ARM 通常对程序员隐藏缓存一致性。
直接回答你的问题:不,你没有任何保证。
重点是 缓存一致性 是您在集群和并行非统一架构中处理的问题。
虽然在这种情况下,编程模型本质上是 多线程 ,但这两个概念 3 是分开的,真正应该困扰您的是如何正确处理多线程,特别是 synchronization and memory order.
你的问题似乎暗示了一个简单的案例,即读者在作者完成后很长时间内被处决。
如果此 属性 是 确实 强制执行,则您不需要任何同步或内存屏障。但是请注意,sleep
函数不符合有效强制执行的条件。
如果您需要同步(从而对内存访问进行排序),那么您需要使用特定于语言的结构,例如 C# 中的 volatile
和 Java、C和C++中的atomics
或[=中的具体说明36=]程序集.
您可能还需要实施关键部分。
如果你真的需要为你的架构手动控制缓存一致性,那么你必须检查感兴趣的规范(通常是数据表和正式论文),因为没有统一的方法来处理它,编译器应该提供一些内在的或运行时应该提供一个库。
所以在上面的直接答案中添加一些东西:不,你没有任何保证,但是当通常 CPU,在普通架构,需要那个资料,反正用最新的就可以了。所以你不用担心那个方面。
请注意 common 和 that 的用法
1 例如,如果您使用 Intel/AMD/ARM CPU,缓存一致性就别想了
2 CPU 本身、本地监视器、系统监视器或特定设备。
3 多线程和缓存一致性。
当进入调度程序以查看是否有与 运行 不同的任务时,缓存往往会在操作系统节拍中断时被刷新。
但是,随着操作系统变得越来越智能,例如 tickless NoHz 以及 CPU 核心数量增加,这种可能性越来越小,您不应该指望它。
超级计算机集群可能不会在几分钟内一次切换任务,因为它们使用的是定制的操作系统代码,不会中断 运行ning 作业,永远不会。计算作业被分配给核心 1-7,没有中断,所有其他工作 运行s 在核心 0 上。
你的问题中混入了两个概念:软件同步和硬件一致性。 Margaret 已经谈到了硬件一致性,所以我不会在这里介绍它。
软件同步
x86 保证如果在 64 位边界上对齐,四字访问将自动执行。但这保证了其他处理器不会读取部分结果(例如 [32bit New]<32bit Old> weird mixture)。它不保证另一个处理器可以看到新分配的值的硬时间期限。让另一个线程等待一段时间并不是一个很好的解决方案,因为首先两个线程需要同步相同的开始时间。所以,如果你需要这样的保证,你需要条件变量来确保另一个线程应该等待。
https://en.wikipedia.org/wiki/Monitor_(synchronization)
总之,如果需要顺序效果,使用条件变量,使用locks/transactional内存等保护变量超过四字或非64位对齐。
顺便说一句,如果您有兴趣,这里有一个有用的 material 缓存一致性。
http://www.cs.cmu.edu/afs/cs/academic/class/15418-s12/www/lectures/10_coherence.pdf