当对页面使用直写式缓存策略时

2023-12-05

我正在阅读 MDS 攻击论文RIDL:流氓飞行数据加载。将页面设置为回写、直写、组合写入或不可缓存,并通过不同的实验确定行填充缓冲区是微架构泄漏的原因。


切线:我知道内存可能是不可缓存的,但我假设可缓存的数据始终缓存在回写式缓存中,即我假设 L1、L2 和 LLC 始终是回写式缓存。

我在我的文章中了解了回写式缓存和直写式缓存之间的差异计算机体系结构书籍。它说:

直写式缓存更容易实现,并且可以使用写缓冲区 独立于缓存来更新内存。此外,读取未命中 成本较低,因为它们不会触发内存写入。在另一 另一方面,回写式缓存会减少传输次数,从而允许更多带宽 到执行 DMA 的 I/O 设备的内存。此外,减少 当我们向下移动层级时,转移变得越来越重要 传输时间增加。一般来说,层次结构越往下的缓存越多 可能使用回写而不是直写。

因此直写式缓存更容易实现。我知道这可以成为一个优势。但是,如果缓存策略可以通过页表属性设置,那么就不会有实现优势——每个缓存都需要能够以回写或直写方式工作。

问题

  1. 每个缓存(L1、L2、LLC)都可以在回写或直写模式下工作吗?那么如果页面属性设置为write-through,那么它们都会是write-through?
  2. 写组合对于 GPU 内存很有用;访问硬件寄存器时,不可缓存是很好的选择。何时应将页面设置为直写?这样做有什么好处呢?
  3. 是否存在直写式缓存(如果它确实是硬件的属性,而不仅仅是由页表属性控制的东西),或者所有缓存都创建为回写式以减少流量的趋势是什么?

每个缓存(L1、L2、LLC)都可以在回写或直写模式下工作吗?

在大多数 x86 微架构中,是的,所有数据/统一缓存都(能够)回写,并在该模式下用于所有普通 DRAM。intel core i7处理器使用哪种缓存映射技术?有一些详细信息和链接。除非另有说明,任何谈论 x86 的人都默认假设 DRAM 页面将是 WB。

AMD Bulldozer 做出了非常规的选择,使用直写式 L1d,并在它和 L2 之间有一个小型 4k 写入组合缓冲区。 (https://www.realworldtech.com/bulldozer/8/)。这有很多缺点,我认为(事后看来)被广泛认为是 Bulldozer 系列的几个弱点甚至设计错误之一(AMD 为 Zen 修复了该系列)。另请注意,Bulldozer 是 CMT 而不是 SMT 的实验(两个弱整数核心共享一个 FPU/SIMD 单元,每个核心都有单独的 L1d 缓存,共享一个 L2 缓存)https://www.realworldtech.com/bulldozer/3/显示系统架构。

当然,Bulldozer L2 和 L3 缓存仍然是 WB,架构师并没有疯。WB 缓存对于减少共享 LLC 和内存的带宽需求至关重要。即使是直写式 L1d 也需要一个写入组合缓冲区,以允许 L2 缓存更大且更慢,从而达到 L1d 未命中时有时命中的目的。也可以看看为什么大多数处理器中L1缓存的大小都小于L2缓存的大小?

直写式缓存可以简化设计(尤其是单核系统),但一般来说,CPU 在几十年前就已经超越了这一点。 (回写式缓存与直写式缓存?)。 IIRC,一些非 CPU 工作负载有时会受益于直写式缓存,特别是没有写分配,因此写入不会污染缓存。 x86 有 NT 存储来避免这个问题。

那么如果页面属性设置为write-through,那么它们都会是write-through?

是的,每个存储都必须在标记为 WT 的页面中一直到达 DRAM。

缓存针对 WB 进行了优化,因为这是每个人都使用的,但希望能够支持将线路传递到外部缓存,而无需从 L1d 逐出。 (所以WT不一定把商店变成类似的东西movntps绕过缓存/驱逐存储。但请检查一下;显然,在某些 CPU 上,至少像 Pentium Pro 系列,L1 中的 WT 存储命中会更新该行,但 L2 中的 WT 命中会驱逐该行,而不是将其带入 L1d。)

何时应将页面设置为直写?这样做有什么好处呢?

基本上从来没有; (几乎?)所有 CPU 工作负载在使用 WB 内存时效果最佳。

操作系统甚至懒得让用户空间轻松(或可能?)分配 WC 或 WT DRAM 页。 (尽管这当然不能证明他们是never有用。)例如在CPU缓存抑制, 我发现a link关于一个从未进入主线内核的 Linux 补丁,该补丁增加了映射页面 WT 的可能性。

WB、WC 和 UC 分别常见于普通 DRAM、设备内存(尤其是 GPU)和 MMIO。

我至少看过一篇论文,针对某些工作量对 WT、WB、UC、WC 进行了基准测试(用 google 搜索,但没有找到,抱歉)。人们测试晦涩的 x86 东西有时会为了完整性而包含它。例如Meltdown 背后的微架构总的来说是一篇好文章(并且与您正在阅读的内容相关)。

WT 的几个优点之一是,存储会立即到达 L3,其他核心的负载可能会受到影响。对于该页面的每个存储来说,这可能是值得的额外成本,特别是如果您小心地将写入操作合并到一个大型 32 字节 AVX 存储中。 (或 64 字节 AVX512 全行写入。)当然,仅将该页面用于共享数据。

不过,我还没有见过有人建议这样做,而且我也没有尝试过。可能是因为对于大多数用例来说,通过 L3 写入的额外 DRAM 带宽并不值得。但也可能是因为您可能必须编写一个内核模块才能以这种方式映射页面。

如果 CPU 从 WT 存储的 L2 或 L3 命中上的外部缓存中逐出,它甚至可能无法完全按照这种方式工作,就像 @Lewis 评论 PPro 记录的那样。

因此,也许我对 WT 的目的的理解是错误的,它旨在(或至少可用)用于设备内存用例,例如 GPU 不会修改的视频 RAM 的部分。

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

当对页面使用直写式缓存策略时 的相关文章

随机推荐

  • cv::RotatedRect 中非零像素的数量

    正如标题所说 我试图找到 cv Mat 的某个区域 即 RotatedRect 内 的非零像素数 对于常规矩形 可以简单地在 ROI 上使用 countNonZeroPixels 然而 ROI 只能是规则的 非旋转的 矩形 另一个想法是绘制
  • 带有 IntelliJ 和 Tomcat 的 Java-ee REST 服务器

    我正在尝试使用 Java ee 实现 REST 服务器 API 如下所示this教程 我使用 Tomcat 而不是 Glassfish 我可以开发一个servlet WebServlet name hello urlPatterns pub
  • Java HTTP 服务器

    我想在本地实现一个 Java HTTP 服务器 我的意思是服务器计算机将在我的控制之下 我预计向其发送请求的客户端不会超过 20 个 我想知道如何去做 我应该使用 J2EE servlet 容器 例如 Apache Tomcat 吗 我可以
  • 如何在重绘时保存先前绘制到画布上的对象?

    每次重绘 SurfaceView 时 之前绘制的内容都会被擦除 如何保存它们的状态 以便我的循环将新对象添加到屏幕上而不删除旧对象 用一个画Bitmap Bitmap mDrawBitmap Canvas mBitmapCanvas Pai
  • 如何从命令行中的脚本运行函数?

    我有一个具有一些功能的脚本 我可以直接从命令行运行其中一个函数吗 像这样的东西吗 myScript sh func 好吧 虽然其他答案是正确的 你当然可以做其他事情 如果你有权访问 bash 脚本 你可以修改它 然后简单地将特殊参数放在最后
  • 超时期限未过,但仍然超时(参见代码)?

    好的 在大约 3 4 分钟的搅拌后 我不断收到此错误 Timeout expired The timeout period elapsed prior to completion of the operation or the server
  • 如何在空手道功能中循环数组值

    我正在尝试循环空手道功能文件中的数组值 在Feature1 feature Scenario1中 我在数组 UUID1 UUID2 UUID3 中有一些值 我想调用另一个功能文件 Feature2 feature 有一个代码来调用DELET
  • QUnit,断言不行吗?

    抱歉 如果这是显而易见的 但是如果我们想断言某个方法返回 false QUnit 中是否有 notOK 或等效函数 我看不出有什么办法可以否定 OK文档 I tried ok 但这没有用 你可以使用 ok method expected t
  • 在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH

    下列的这个问题 我通过 HomeBrew 安装了 ANTLR brew install antlr 它安装在 usr local Cellar antlr
  • 遍历组并为每个 R 创建绘图

    我正在尝试映射 循环鸢尾花数据集中的物种列 为每个物种创建一个图 下面的脚本返回三个图表 但所有图表都绘制了相同的数据 并且不按物种划分 地图函数似乎忽略了species list 只查看整个数据帧 一直在尝试不同的方法 但无法使任何工作发
  • Swift 3 和 Swift 4 中的 WebService API 方法?

    我是新来的SwiftiOS 和我想在单独的类中创建一个单独的方法 例如NSObject 的 Web 服务 以便我可以在任何 ViewController 中使用它并解析任何类型的JSON响应使用NSURLSession and Alamof
  • 用于自动化 ncurses 类型 telnet 会话的跨平台解决方案

    背景 我在网络和电信领域的部分工作涉及当传统硬件无法在其他接口中提供简单的解决方案时自动执行 telnet 会话 许多旧设备只能通过工艺端口 RS 232 串行端口 SNMP 或 Telnet 进行访问 有时 telnet 是访问特定信息的
  • 将数组从 JSON 文件导入到 Typescript 文件中

    我有一个 JSON 文件 其中包含一个数组对象 如下所示 VergiNo XXXXXXX VergiNo YYYYYY VergiNo ZZZZZZ 我将此 JSON 文件导入到我的 Typescript 文件中 import as fir
  • PHP 会话变量与局部变量互换?

    我遇到了一个关于 php ini 中的会话变量和局部变量的非常奇怪的问题 我试图弄清楚我是否不了解 php 中的会话 或者这是否是我的主机使用的 php 版本的问题 这是一个非常简单的代码来演示这个奇怪的问题 session start v
  • C 和 C++ 中 += 的结果是什么?

    我有以下代码 include
  • 如何区分bool和int

    我有一个清单 它包含不同类型的值 例如 1 2 3 a False 0 5 0 3 任务是将所有零移动到列表的末尾 它应该看起来像这样 1 2 3 a False 5 3 0 0 如何区分布尔值False from 0 我正在尝试将它们与以
  • 1 viewmodel多条路线:生命周期

    我想要有几个不同的路线指向相同的视图 视图模型 并且我已经成功地实现了这一点 route formulation moduleId formulation title Formulation nav 6 route fabrication
  • 为什么 Typescript 允许子类型化?

    根据文档 TypeScript 中的类型兼容性基于结构子类型 所以这是可能的 type Person name string const developer name Joe language Typescript this is ok b
  • 一表两列MYSQL查询挑战

    考虑一个名为 comments 的 MYSQL 表 其中包含 2 列 主机名 和 用户名 如何返回按主机名排序的列表 其中第二列是与每个主机名关联的用户名列表 我可以看到如何使用 py 这样的脚本语言来做到这一点 但是它可以作为标准 SQL
  • 当对页面使用直写式缓存策略时

    我正在阅读 MDS 攻击论文RIDL 流氓飞行数据加载 将页面设置为回写 直写 组合写入或不可缓存 并通过不同的实验确定行填充缓冲区是微架构泄漏的原因 切线 我知道内存可能是不可缓存的 但我假设可缓存的数据始终缓存在回写式缓存中 即我假设