如果数据已经在缓存中,那么非临时存储会发生什么?

时间:2015-12-28 21:46:18

标签: c++ x86 sse cpu-cache

当您使用非临时商店时,例如movntq,并且数据已经在缓存中,商店是否会更新缓存而不是写入内存?或者它会更新缓存行并写出来,驱逐它吗?或者是什么?

这是一个有趣的困境。假设线程A正在加载包含x和y的缓存行。线程B使用NT存储写入x。线程A写入y。如果B的存储到x可以在A的负载发生时传输到内存中,那么这里会有数据竞争。如果A看到x的旧值,但是X的写入已经发生,那么稍后写入y并最终写回高速缓存行将破坏不相关的值x。我假设处理器以某种方式阻止了这种情况的发生?如果允许的话,我无法看到任何人如何使用NT商店构建可靠的系统。

2 个答案:

答案 0 :(得分:5)

您描述的所有行为都是非临时存储的合理实现。实际上,在现代x86 CPU上,实际的语义是对L1缓存没有影响,但L2(以及更高级别的缓存,如果有的话)不会驱逐缓存行来存储非临时提取结果

没有数据竞争,因为缓存是硬件一致的。决定驱逐缓存行不会以任何方式影响这种一致性。

答案 1 :(得分:2)

在多核CPU(即比Pentium M更新的CPU)上,如果目标存储行已经存在于缓存层次结构中,则将由NT存储驱逐 em> NT存储区发生了。

如果修改了缓存行(并且需要回写),这可能效率很低;在这种情况下,常规商店+ clflush可能会更好。 IDK:清洁生产线需要多少费用; NT存储本身在访问内存控制器的过程中通过高速缓存层次结构进行移动可能可以进行驱逐,以确保在修改RAM之后,其他任何内核仍然无法拥有陈旧的高速缓存副本。

来自Intel's x86 volume 1 manual, ch 10.4.6.2 Caching of Temporal vs. Non-Temporal Data

  

如果程序使用以下指令之一指定了非临时存储   并且目标区域的内存类型为回写(WB),直写(WT)或写组合​​(WC),则处理器将执行以下操作:

     
      
  • 如果高速缓存层次结构中存在要写入的内存位置,则将逐出高速缓存中的数据。 1

         

    1 一些较旧的CPU实现(例如奔腾M)允许使用非临时存储指令写入的地址为   如果内存类型不是WC并且行已在缓存中,则就地更新。

  •   
  • 非时间数据通过WC语义写入内存。

  •   
     

另请参阅:《英特尔®64和IA-32架构软件开发人员手册》第3A卷第11章“内存缓存控制”。


来自Intel's optimization manual 7.4.1.3内存类型和非临时存储。我已经将[]汇总为摘要。

  

内存类型可以优先于非时间提示,从而导致   以下注意事项:

     
      
  • [对于UC和WP,NT被忽略:强顺序不可缓存内存。]
  •   
  • 如果程序员指定了Write-Combining(WC)的弱排序不可缓存内存类型,则非时间存储和   区域具有相同的语义,没有冲突。

  •   
  • 如果程序员为可缓存内存指定了非临时存储(例如,Write-Back)   (WB)或直写(WT)内存类型),可能会导致两种情况:

         
        
    • —案例1 —如果数据存在于缓存层次结构中,则该指令将确保一致性。一种   特定的处理器可能选择不同的方法来实现此目的。以下方法是   可能:

           

      (a)在缓存层次结构中就地更新数据,同时保留分配给该区域的内存类型语义或
        (b)从缓存中逐出数据并写入新的   非临时数据到内存(具有WC语义)。

           

      对于将来的处理器,方法(单独或组合)可能会有所不同。奔腾4,英特尔   Core Solo和Intel Core Duo处理器实施后一种策略(从所有处理器中清除数据   处理器缓存)。奔腾M处理器实现了两种方法的组合。

           

      如果流式存储命中一级缓存中存在的行,则将合并存储数据   放在一级缓存中。如果流媒体商店碰到第二级中的一行,   该行和存储的数据从第二级刷新到系统内存。 [认为整段内容都在描述奔腾M的“组合”方法]

    •   
    • —案例2 —如果数据不在缓存层次结构中,并且目标区域已映射   作为WB或WT;事务将被弱排序,并受所有WC内存语义的约束。   此非临时存储区不会写分配。不同的实现方式可以选择折叠并合并这些存储。

    •   
  •