assembly - WC vs WB内存? x86_64上的其他类型的内存?

标签 assembly memory x86-64 cpu-cache memory-mapping

您能描述x86_64上WC和WB内存之间的含义和区别吗?为了完整起见,请描述x86_64上的其他类型的内存(如果有)。

最佳答案

我将首先从写回缓存(WB)开始,因为它更易于理解。
写回缓存
顾名思义,此缓存策略将尝试尽可能长时间地延迟对系统内存的写入。
理想情况下,此想法是仅使用缓存。
但是,由于高速缓存的有限大小小于内存的有限大小,并且其内部组织结构请参见Wikipedia's Cache article引入了一些冲突的别名,因此有时必须将高速缓存行逐出到内存中。
这是一个写回事件-写回事件的另一个来源是缓存一致性机制,请参见MESI
这是WB的基本思想,从技术上讲,通过对四个主要事件采取的措施来定义缓存策略。

Event              | Action
-------------------+----------------------------------------------
Read hit           | Read from the cache line
-------------------+----------------------------------------------
Read miss          | Fill the line then read from the cache line
-------------------+----------------------------------------------
Write hit          | Write to the cache line
-------------------+----------------------------------------------
Write miss         | Fill the line then write to the cache line*

* Since P6, we will assume this is always the case
如您所见,没有写入内存。这是高速缓存的限制的副作用,继而强行将其逐出。
其他高速缓存属性(例如替换策略,一致性,允许的推测性行为(以及所有这些如何影响可视性和内存访问顺序))与高速缓存策略正交,因此不在此答案之列。
英特尔为每种策略隐式设置了其中一些属性,但这只是为了节省一些配置位。
为了完整起见,这是与其他缓存策略的比较表。
写合并(WC)被有意地忽略了。
Legend
   LF = Line Fill;         LR = Read from line;   MR = Read from memory
   LW = Write to line;     MW = Write to memory

   WB = Write back;        UC = Uncachable (Not cached);
   WT = Write through;     WP = Write protect

Event              | WB      |  UC | WT       | WP     |
-------------------+---------+-----+----------+--------+----------
Read hit           | LR      | MR* | LR       | LR     |
-------------------+---------+-----+----------+--------+----------
Read miss          | LF, LR  | MR  | LF, LR   | LF, LR |
-------------------+---------+-----+----------+--------+----------
Write hit          | LW      | MW  | LW, MW** | MW***  |
-------------------+---------+-----+----------+--------+----------
Write miss         | LF, LW  | MW* | MW       | MW     |

* A hit on a UC region can happen if the cache type has been
  changed without invalidating the cache. In truth for UC talking about
  hits is a bit misleading. Caching is bypassed, so it is actually a
  N.A. case.   

** The line can be invalidated as the result of the eviction operation
   used.

*** Evict the line, even if it was Modified or Exclusive, e.g. because of 
    writes via other current or previous mapping for the same physical page.
    Writing directly to memory by bypassing the caches also invalidates
    all the copies of the affected line in other processors.
备注:WP和WT之间的区别在于后者可以看作是“刺穿”缓存,而前者可以“绕过”缓存。
写结合
WC并不是真正的缓存策略,但是由于它与缓存策略紧密相关,因此将在其中进行讨论。
我发现英特尔SDM在这个问题上非常令人困惑,这是我到目前为止对此事的解释。
欢迎更正!
英特尔在WC上有一份旧的可用here文件-其内容已包含在英特尔SDM 3的11.3.1节中,但是这样做,英特尔丢失了原始文档中可用的某些上下文和结构。
WC的想法是在诸如总线事务或高速缓存一致性事务之类的持久操作之前或期间合并写入。
为了实现这一点,处理器具有许多WC缓冲区-请勿将其与高速缓存行的存储缓冲区混淆。
WC缓冲区是一个单独的实体!
WC缓冲区的数量是有限的:在P6中(因此在Pentium M中)有6个WC缓冲区,Pentium 4有8个,并且自Nehalem以来有10个WC缓冲区,请参阅《英特尔优化手册》第3.6.10节。
每个WC缓冲区的大小尚未在体系结构上定义,但到目前为止,它一直与高速缓存行大小相同(因此P6为32字节,其他为64字节)。
WC缓冲区位于缓存之前。
现在,WC确实意味着两件事:
  • 在允许CPU写高速缓存行之前,如果发生写未命中,则必须执行RFO(读取所有权)来通知其他CPU其高速缓存的数据(如果有的话)是无效的。
    由于这可能需要很长时间,因此CPU将存储区停在WC缓冲区中并继续工作。然后,缓存子系统将自动将WC缓冲区移动到适当的缓存。
    如果连续存储到正在执行RFO的同一行,它们将全部沉入WC缓冲区。
  • 如果内存类型不涉及高速缓存,则WC缓冲区将在商店完全转移到总线之前充当商店的 parking 场。
    开始总线事务会花费一些开销,但是一旦开始,就可以非常连续地在连续的突发(每个突发实际上是8个字节)中传输数据。
    写入少于内存总线宽度的数据会浪费内存带宽-就像使总线(真正的总线,一种用于人的总线)的运行空间减少一半一样。
    因此,WC正在尝试利用整个内存总线的宽度。

  • 备注:UC内存类型绕过所有缓存子系统,包括WC缓冲区。 WC内存类型绕过缓存,但不绕过WC缓冲区。
    在第一种情况下,WC允许CPU在长时间运行的过程中继续其工作,在第二种情况下,它允许有效地传输数据。
    英特尔在两种情况下都使用相同的术语WC,在我看来,这引起了困惑。
    英特尔SDM读取到WC仅在WC内存类型区域上被允许,但后来声称它适用于所有内存类型,并在每个缓存策略的描述中进行报告。
    我相信这是因为Intel指的是上述两个WC。
    我相信第二种类型是原始类型,并且当MESI流行时,WC缓冲区已被重用。

    编辑
    我忘了提到WC内存类型是不可缓存的(但仍是推测性的,有意排除了推测)。
    彼得·科德斯(Peter Cordes)用his comment完美地总结了一下:

    WC is short-hand for USWC: "Uncacheable Speculative Write-Combining".
    The key point is that it's an uncacheable memory type, which is why movntdqa loads are useful (to load a [store buffer entry, that is as wide as a] full cache line, instead of doing separate accesses to DRAM for separate loads [residing in an address range that could be cached ] from the same cache line)


    我刚刚在括号中添加了文字,因为我相信他使用术语“高速缓存行”作为度量单位和内存地址的区别属性。

    在给定的时刻,只能有四个WC缓冲区处于事件状态。
    英特尔优化手册还报告说,只能使用两个方法来组合对缓存的写入。
    当使用WC将存储组合到内存时,处理器不会强制执行一致性。
    WC缓冲区不会被监听,此外,当前事件的WC缓冲区之间不会强制执行任何顺序(首先溢出)。
    如果必须将WC逐出,则可以通过执行一次总线事务(如果WC缓冲区都脏了),执行最多8(64/8)或4(32/8)总线事务(如果WC缓冲区包含部分数据)来完成。 。
    同样,当溢出带有部分数据的WC缓冲区时,在块之间不执行任何排序。
    一旦软件在缓冲区大小之外写入,P6便退出WC缓冲区,确切的算法已定义为实现-通常会有一个时间窗口,以允许软件合并写入。
    可以通过访问UC内存类型区域或在发生特定事件时强制逐出(请参阅本节开头的链接文章)。

    关于assembly - WC vs WB内存? x86_64上的其他类型的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45623007/

    相关文章:

    c - posix_memalign 与 mmap 有何不同

    xcode - 终端中出现 "Undefined symbols for architecture x86_64"但 xcode 中没有错误

    c - 用于将 C 代码转换为 MIPS 汇编代码的 gcc 命令

    performance - 为什么 SSE 标量 sqrt(x) 比 rsqrt(x) * x 慢?

    c++ - 警告 #13212 : Reference to ebx in function requiring stack alignment

    找不到预先编写的函数的程序集

    c++ - C++类构造函数中的内存泄漏

    java - 我们可以从 java 应用程序内部限制 java 应用程序的内存吗?

    c - x86_64 调用约定和堆栈帧

    ios - 在独立 SDK 中注册内存警告通知