写组合缓冲区位于哪里? x86

2024-03-14

Write-Combine 缓冲区在物理上是如何连接的?我见过说明许多变体的框图:

  • L1 和内存控制器之间
  • CPU 的存储缓冲区和内存控制器之间
  • CPU 的 AGU 和/或存储单元之间

它依赖于微架构吗?


写缓冲区在不同的处理器中可以有不同的目的或不同的用途。这个答案可能不适用于未特别提及的处理器。我想强调的是,术语“写缓冲区”在不同的上下文中可能有不同的含义。此答案仅涉及 Intel 和 AMD 处理器。

Intel 处理器上的写入组合缓冲区

每个高速缓存可能伴随有零个或多个行填充缓冲区(也称为填充缓冲区)。 L2 填充缓冲区的集合称为超级队列或超级队列(超级队列中的每个条目都是一个填充缓冲区)。如果高速缓存在逻辑核心或物理核心之间共享,则关联的填充缓冲区也在核心之间共享。每个填充缓冲区可以保存单个高速缓存行和描述高速缓存行(如果已被占用)的附加信息,包括高速缓存行的地址、内存类型和一组有效位,其中位的数量取决于高速缓存行的粒度。跟踪缓存行的各个字节。在早期的处理器中(例如奔腾II https://ieeexplore.ieee.org/abstract/document/865866/),只有一个填充缓冲区能够进行写组合(和写折叠)。随着更新的处理器的出现,行缓冲区和能够进行写组合的行缓冲区的总数稳步增加。

Nehalem 到 Broadwell 在每个 L1 数据缓存处都包含 10 个填充缓冲区。 Core 和 Core2 每个物理核心有 8 个 LFB。根据this https://github.com/Kobzol/hardware-effects/issues/1,Skylake 上有 12 个 LFB。 @BeeOnRope 观察到 Cannon Lake 上有 20 个 LFB。我在手册中找不到明确的说明,表明 LFB 与所有这些微架构上的 WCB 相同。然而,这article https://software.intel.com/en-us/articles/copying-accelerated-video-decode-frame-buffers/英特尔的一位人士写的:

请参阅英特尔® 64 和 IA-32 架构优化参考 特定处理器中填充缓冲区数量的手册; 通常该数字是 8 到 10。请注意,有时这些也是 被称为“写入组合缓冲区”,因为在一些较旧的 处理器仅支持流存储。

我认为 LFB 这个术语是由 Intel 在 Intel Core 微架构中首次引入的,其中所有 8 个 LFB 也是 WCB。基本上,英特尔当时偷偷地将 WCB 更名为 LFB,但此后并没有在其手册中澄清这一点。

同一句话还说,术语 WCB 用于较旧的处理器,因为它们不支持流负载。这可以解释为 LFB 也被流加载请求使用(MOVNTDQA)。然而,第 12.10.3 节说,流式加载将目标行提取到称为流式加载缓冲区的缓冲区中,这些缓冲区在物理上显然与 LFB/WCB 不同。

行填充缓冲区用于以下情况:

(1)填充缓冲区是在缓存中的加载未命中(请求或预取)时分配的。如果没有可用的填充缓冲区,则加载请求会不断堆积在加载缓冲区中,这最终可能导致问题阶段停滞。在加载请求的情况下,分配的填充缓冲区用于临时保存来自内存层次结构较低级别的请求行,直到它们可以写入高速缓存数据阵列。但是,即使高速缓存行尚未写入高速缓存数据阵列,该高速缓存行的请求部分仍然可以提供给目标寄存器。根据帕特里克·费伊(英特尔) https://software.intel.com/en-us/forums/software-tuning-performance-optimization-platform-monitoring/topic/282055:

如果您在 PDF 中搜索“填充缓冲区”,您可以看到该行 填充缓冲区 (LFB) 在 L1D 未命中后分配。 LFB 持有 数据传入以满足 L1D 未命中但在所有数据被发送之前 准备写入 L1D 缓存。

(2)填充缓冲区被分配到 L1 高速缓存的可高速缓存存储上,并且目标行不处于允许修改的一致性状态。我的理解是,对于可缓存存储,只有 RFO 请求保存在 LFB 中,但要存储的数据会在存储缓冲区中等待,直到目标行被提取到为其分配的 LFB 条目中。 Intel 优化手册第 2.4.5.2 节中的以下声明支持了这一点:

L1 DCache 可以通过分配维持多达 64 个加载微操作 直到退休。它可以维持多达 36 家商店的运营 分配直到存储值被提交到缓存或写入 在非临时存储的情况下到行填充缓冲区(LFB)。

这表明如果目标行不在 L1D 中,则可缓存存储不会提交到 LFB。换句话说,存储必须在存储缓冲区中等待,直到目标行写入 LFB,然后在 LFB 中修改该行,或者目标行写入 L1D,然后修改该行在L1D中。

(3)填充缓冲区分配在 L1 高速缓存中不可高速缓存的写组合存储上,无论该行是否在高速缓存中或其一致性状态。可以在单个 LFB 中组合和折叠同一缓存行的 WC 存储(对同一行中的同一位置进行多次写入将使程序顺序中的最后一个存储覆盖先前的存储)。当前在 LFB 中分配的请求之间不维护排序。因此,如果有两个 WCB 正在使用,则无论存储相对于程序顺序的顺序如何,都不能保证哪个将首先被驱逐。这就是为什么即使所有存储都按顺序退役提交,WC 存储也可能变得全局可观察到无序(尽管 WC 协议允许 WC 存储无序提交)。此外,WCB 不会被窥探,因此只有在到达内存控制器时才变得全局可观察。更多信息可以在 Intel 手册 V3 的第 11.3.1 节中找到。

一些 AMD 处理器 https://sites.utexas.edu/jdm4372/2018/01/01/notes-on-non-temporal-aka-streaming-stores/使用与非临时存储的填充缓冲区分开的缓冲区。 P6(第一个实现 WCB)和 P4 中还有许多 WCB 缓冲区专用于 WC 内存类型(不能用于其他内存类型)。在 P4 的早期版本上,有 4 个这样的缓冲区。对于支持超线程的 P4 版本,当启用超线程并且两个逻辑核心都在运行时,WCB 在两个逻辑核心之间静态分区。然而,现代英特尔微架构竞争性地共享所有 LFB,但我认为为每个逻辑核心至少保留一个可用,以防止饥饿。

(4)的文档L1D_PEND_MISS.FB_FULL指示 UC 存储分配在相同的 LFB 中(无论该行是否在高速缓存中或其一致性状态)。与可缓存存储类似,但与 WC 不同,UC 存储不会合并在 LFB 中。

(5)我通过实验观察到来自IN and OUT指令也分配在 LFB 中。有关更多信息,请参阅:使用环形总线拓扑的Intel CPU如何解码和处理端口I/O操作 https://stackoverflow.com/questions/55042577/how-do-intel-cpus-that-use-the-ring-bus-topology-decode-and-handle-port-i-o-oper.

附加信息:

填充缓冲区由高速缓存控制器管理,该控制器连接到其他级别的其他高速缓存控制器(或者在 LLC 的情况下为内存控制器)。当请求命中缓存时,不会分配填充缓冲区。因此,在缓存中命中的存储请求将直接在缓存中执行,而在缓存中命中的加载请求将直接从缓存中得到服务。当从高速缓存中逐出一行时,不会分配填充缓冲区。被逐出的行被写入它们自己的缓冲区(称为写回缓冲区或逐出缓冲区)。这里有一个patent https://patents.google.com/patent/US7206865B2/en来自 Intel,讨论了 I/O 写入的写入组合。

我进行了一项与我所描述的非常相似的实验here https://stackoverflow.com/questions/54541157/the-inner-workings-of-spectre-v2即使同一线路有多个负载,也可以确定是否分配单个 LFB。事实证明确实如此。首次加载回写式 L1D 高速缓存中未命中的行时,会为其分配一个 LFB。稍后对同一高速缓存行的所有加载都会被阻止,并且块代码会写入其相应的加载缓冲区条目中,以指示它们正在等待该 LFB 中保存的同一请求。当数据到达时,L1D 缓存向加载缓冲区发送唤醒信号,并且当至少有一个加载端口可用时,该行上等待的所有条目都会被唤醒(解除阻塞)并计划发送到 L1D 缓存。显然,内存调度程序必须在未阻塞的负载和刚刚从 RS 分派的负载之间进行选择。如果在所有等待负载有机会得到服务之前线路因某种原因被驱逐,那么它们将再次被阻塞,并且 LFB 将再次分配给该线路。我没有测试过存储情况,但我认为无论什么操作,都会为一行分配一个LFB。当需要时,LFB 中的请求类型可以从预取提升为需求加载,再从推测 RFO 提升为需求 RFO。我还根据经验发现,在刷新管道时,不会删除在错误预测的路径上从 uops 发出的推测请求。它们可能会被降级为预取请求。我不知道。

AMD 处理器上的写组合缓冲区

我之前提到过,根据article https://sites.utexas.edu/jdm4372/2018/01/01/notes-on-non-temporal-aka-streaming-stores/有一些 AMD 处理器使用与非临时存储的填充缓冲区分开的缓冲区。我引用那篇文章:

在较旧的 AMD 处理器(K8 和 Family 10h)上,非临时存储 使用一组四个独立的“写组合寄存器” 用于 L1 数据高速缓存未命中的八个缓冲区中的一个。

The "on the older AMD processors" part got me curious. Did this change on newer AMD processors? It seems to me that this is still true on all newer AMD processors including the most recent Family 17h Processors (Zen). The WikiChip article https://en.wikichip.org/wiki/amd/microarchitectures/zen on the Zen mircoarchitecture includes two figures that mention WC buffers: this https://en.wikichip.org/wiki/File:zen_block_diagram.svg and this https://en.wikichip.org/wiki/File:amd_zen_hc28_memory.png. In the first figure, it's not clear how the WCBs are used. However, in the second one it's clear that the WCBs shown are indeed specifically used for NT writes (there is no connection between the WCBs and the L1 data cache). The source for the second figure seems to be these slides http://hotchips.org/wp-content/uploads/hc_archives/hc28/HC28.23-Tuesday-Epub/HC28.23.90-High-Perform-Epub/HC28.23.930-X86-core-MikeClark-AMD-final_v2-28.pdf1. I think that the first figure was made by WikiChip (which explains why the WCBs were placed in an indeterminate position). In fact, the WikiChip article does not say anything about the WCBs. But still, we can confirm that the WCBs shown are only used for NT writes by looking at Figure 7 from the Software Optimization Guide for AMD Family 17h Processors https://developer.amd.com/resources/developer-guides-manuals/ manual and the patent https://patents.google.com/patent/US20180046463A1/en for the load and store queues for the Family 17h processors. The AMD optimization manual states that there are 4 WCBs per core in modern AMD processors. I think this applies to the K8 and all later processors. Unfortunately, nothing is said about the AMD buffers that play the role of Intel fill buffers.


1 https://ieeexplore.ieee.org/abstract/document/865866/迈克尔·克拉克,AMD 全新高性能 x86 核心设计 http://www.hotchips.org/archives/2010s/hc28/, 2016.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

写组合缓冲区位于哪里? x86 的相关文章

随机推荐

  • Google Drive API“监视”文件夹中,如何知道添加了哪些文件

    我正在运行一个测试端点 当我将文件放入监视文件夹时 我收到一个带有标头的请求X Goog Resource State update 但我似乎没有获得添加文件的 ID I get X Goog Resource Id我原以为这可能是新文件
  • 如何使 README_FOR_APP 的内容出现在 doc/app/index.html 中

    我想要的内容doc README FOR APP出现在doc app index html 当我做rake doc app 目前 内容为 这是 Rails 应用程序文档的 API 文档 To see README FOR APP 我必须点击
  • 中没有足够的空间。如何添加多行

    我想在选项文本下添加描述该选项的行 默认情况下 mat select 限制字符数并在行末尾添加 我想要有需要的多行选项 斯塔克闪电战演示 https stackblitz com edit angular wj9svw https stac
  • Python-如何检查Redis服务器是否可用

    我正在开发一个用于访问 Redis 服务器的 Python 服务 类 我想知道如何检查Redis服务器是否正在运行 而且如果不知何故我无法连接到它 这是我的代码的一部分 import redis rs redis Redis localho
  • Ruby 项目帮助。无法从数组中获取已保存的实例

    TLDR 我正在开发一个使用 API 创建实例的项目 我希望能够回忆起所有的实例 但不知道如何回忆 我对 Ruby 和一般编程还比较陌生 所以我希望我能很好地解释一切 这是我的代码 class Suggestion attr accesso
  • 使用 AJAX 在 Bootstrap Modal 上调用 PHP 函数

    我使用 PHP 循环在我的页面上回显了用户列表 当我单击每个用户的名称时 会弹出一个 Bootsrap 模态并显示该用户的更多详细信息 链接看起来像这样 a href user UserName a 如您所见 我将用户的 ID 传递给 Bo
  • Ruby on Rails、LinkedIn:模块错误

    有人遇到过这个错误吗 NoMethodError undefined method new for LinkedIn Module 我认为这与omniauth和linkedin有关 这是我的 Gemfile gem omniauth gem
  • 要构建 php MVC,我需要注意哪些命名约定?

    我对 OO PHP 还很陌生 但是我了解它是如何工作的 并准备开始为我正在开发的大型网站构建 MVC 我知道没有必要这么写你必须这样做但还是得有一些正常的习惯 类名 驼峰命名法 下划线 类文件 与类相同 url post get 控件名称
  • Django 更新查询集以更改外键的 ID

    我正在尝试更新一堆对象的 id 以及引用这些对象的相关表 class Test models Model id models IntegerField primary key True class Question models Model
  • JavaScript RegEx 确定电子邮件的域(例如 yahoo.com)

    使用 JavaScript 我想接受输入 第一次验证电子邮件是否有效 我解决了这个问题 2 验证电子邮件地址是否来自 yahoo com 有人知道可以提供域名的正则表达式吗 thxs var myemail email protected
  • 是 .yaml 还是 .yml?

    根据yaml org http www yaml org faq html 官方文件扩展名是 yaml Quote YAML 文件有官方扩展名吗 请尽可能使用 yaml 然而 互联网上对于使用哪个扩展似乎存在分歧 如果你抬头看网上的例子 h
  • 如何在控件实例化后立即发送自定义事件消息?

    创建此自定义控件并在客户端中测试它时 发送 ValueChanged 事件时出现空异常错误 自定义控件来源 using System using System Collections Generic using System Compone
  • 从内存缓冲区初始化 C++ std::istringstream?

    我有一个内存块 不透明 我想通过他们的 C 适配器将其存储在 mySQL 中的 Blob 中 适配器需要一个 istream virtual void setBlob unsigned int parameterIndex std istr
  • 浏览器的HTTP缓存的存储位置在哪里?磁盘或内存

    浏览器的HTTP缓存的存储位置在哪里 磁盘或内存 我只是想知道为什么有些文件来自磁盘缓存而另一些文件来自内存缓存 HTTP 缓存背后的机制是什么 哪个缓存的优先级更高 看起来脚本和样式表存储在磁盘中 而图像和字体存储在内存中 也许是解决方案
  • Django 查询选择不同的字段对

    我的 提交 字段有一个用户和一个问题 如何获得 SQL 搜索结果 该结果将给出每个用户 问题对仅包含一个结果的列表 模型是这样的 class Problem models Model title models CharField Title
  • 使用 CSS 3D 变换从 DOM 对象接收变换后的鼠标事件数据

    目前 JavaScript 鼠标事件中是否有任何数据可以让我轻松查找或计算相对于转换元素的 3D 空间的鼠标位置 为了直观地说明 左边是没有 3d 矩阵的 div 右边是经过 3d 变换的 div o是鼠标事件的起源 o gt o 在下面的
  • Python - Pandas 删除 Excel 中的特定行/列

    我有以下 Excel 文件 我想清理特定的行 列 以便我可以进一步处理该文件 我已经尝试过这个 但我没有设法删除任何空白行 我只能设法从包含数据的行中修剪掉 在这里 我试图只保存第三行及以后的数据 xl pd ExcelFile MRD x
  • TemplateInputException:解析模板时出错 ****,模板可能不存在

    我正在使用 Spring Boot 和 mySql 数据库 我正在尝试通过团队表过滤搜索 最初这个表是一个 thymeleaf 表 参见我的相关 SO 问题 但在用尽互联网上可用的所有资源后 没有成功 我决定以不同的方式实现搜索 我发现了一
  • 通过 C# 和 OleDb 将行插入 Excel 电子表格

    我需要以编程方式将一行多次插入 Excel 电子表格中 我需要实际上插入一个新行并且不插入数据 也就是说 我实际上需要将所有其他行向下移动一位 我目前正在使用 OleDB 插入数据本身 如下所示 Note I have missed som
  • 写组合缓冲区位于哪里? x86

    Write Combine 缓冲区在物理上是如何连接的 我见过说明许多变体的框图 L1 和内存控制器之间 CPU 的存储缓冲区和内存控制器之间 CPU 的 AGU 和 或存储单元之间 它依赖于微架构吗 写缓冲区在不同的处理器中可以有不同的目