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

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(使用前将#替换为@)

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

  • 从汇编程序获取命令行参数

    通读 专业汇编语言书籍 似乎它提供了用于读取命令行参数的错误代码 我纠正了一点 现在它从段错误变成了读取参数计数 然后是段错误 这是完整的代码 data output1 asciz There are d params n output2
  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • Verilog 双向握手示例

    我正在完成一个项目 要求是处理器内部功能单元之间的双向握手 我知道它是什么 但是有没有任何 标准 或一个简单的例子 我唯一能想到的就是两个单元之间 当它们之间有一条数据线并且当 X 发送到 Y 时 会给出一个单独的 发送 信号 当 Y 接收
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 为什么在强度降低乘法和循环进位加法之后,这段代码的执行速度会变慢?

    我正在读书阿格纳 雾 https en wikipedia org wiki Agner Fog s 优化手册 https en wikipedia org wiki Agner Fog Optimization 我遇到了这个例子 doub
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • ARM 系统调用的接口是什么?它在 Linux 内核中的何处定义?

    我读过有关 Linux 中的系统调用的内容 并且到处都给出了有关 x86 架构的描述 0x80中断和SYSENTER 但我无法追踪 ARM 架构中系统调用的文件和进程 任何人都可以帮忙吗 我知道的几个相关文件是 arch arm kerne
  • 大会,你好世界问题

    我正在 Linux 上学习 asm noobuntu 10 04 我得到了以下代码 http asm sourceforge net intro hello html http asm sourceforge net intro hello
  • 将 mmap 内核启动参数保留的内存映射到用户空间

    正如中所讨论的this https stackoverflow com q 1911473 143897问题 我在启动时使用内核启动参数保留一个内存块memmap 8G 64G 我写了一个字符驱动程序 http pete akeo ie 2
  • Linux、ARM:为什么仅当启动时存在 I2C GPIO 扩展器时才创建 gpiochip

    在 imx6sx 硬件平台 NXP 嵌入式 ARM 上使用 Linux 3 14 52 问题是设备树中指定的 PCF8575 I2C GPIO 扩展器不会实例化为 sys class gpio 结构中的设备 除非它们在内核启动期间存在 这些
  • 为什么如果内存组织为字,则程序计数器加 1;如果内存组织为字节,则程序计数器加 2?

    如果在计算机中一条指令是 16 位 并且如果存储器被组织为 16 位字 则通过在当前指令的地址中加 1 来计算下一条指令的地址 如果内存是按字节组织的 可以单独寻址 那么我们需要在当前指令地址上加二 得到顺序执行的下一条指令的地址 为什么会
  • 动态更改 eBPF 映射大小

    在内核中 eBPF 映射可以定义为 struct bpf map def SEC maps my map type BPF MAP TYPE HASH key size sizeof uint32 t value size sizeof s
  • 我们如何计算这段代码片段中缓存的读取/未命中次数?

    鉴于我目前正在学习的这本教科书中的代码片段 Randal E Bryant David R O Hallaron 计算机系统 程序员的视角 第 3 版 2016 年 Pearson 全球版 因此本书的练习可能是错误的 for i 31 i
  • 为什么 FMA _mm256_fmadd_pd() 内在函数有 3 个 asm 助记符:“vfmadd132pd”、“231”和“213”?

    有人可以向我解释一下为什么融合乘法累加指令有 3 种变体 vfmadd132pd vfmadd231pd and vfmadd213pd 而只有一个 C 内在函数 mm256 fmadd pd 为了简单起见 在 AT T 语法中 有什么区别
  • 在网络处理中使用自旋变体

    我编写了一个与网络过滤器挂钩交互的内核模块 网络过滤器挂钩在 Softirq 上下文中运行 我正在访问全局数据结构 哈希表 来自软中断上下文以及进程上下文 进程上下文访问是由于sysctl文件用于修改哈希表的内容 我正在使用 spinloc
  • “perf record”或“perf-record”可以对子进程进行采样吗?

    假设我有一个harness二进制文件 它可以根据命令行选项生成不同的基准 我对这些基准测试非常感兴趣 我有3个选择 更改线束二进制文件以生成perf record运行基准测试并进行采样的子进程 just do perf record har
  • 为什么我的代码显示垃圾?

    当我也想打印列表中的每个数字时 我的代码显示垃圾 有什么问题吗 输出应如下所示 给定的数组是 2G 4 PT为什么这是垃圾总数是 7 Code ASSUME CS CODE DS DATA SS STK ORG 0000H DATA SEG
  • 避免 gcc 函数序言开销?

    我最近遇到了很多 gcc 在 x86 上生成非常糟糕的代码的函数 它们都符合以下模式 if some condition do something really simple and return else something comple
  • 使用sk_buff添加以太网帧头

    我有一个捕获传出互联网流量的内核模块 Netfilter hook LOCAL OUT 在此挂钩处 仍然没有以太网标头 我构建了以太网头并且可以使用了 但是如何将其连接到skb这样我就可以将整个 skb 结构发送到dev queue xmi
  • 整数溢出问题

    我不断遇到整数溢出问题 我不知道如何解决它 有人可以帮忙吗 edx 包含 181 eax 包含 174 xor eax edx mov edx 2 div edx 假设你谈论的是x86 div edx这实际上没有意义 32位div将edx

随机推荐

  • 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 流氓飞行数据加载 将页面设置为回写 直写 组合写入或不可缓存 并通过不同的实验确定行填充缓冲区是微架构泄漏的原因 切线 我知道内存可能是不可缓存的 但我假设可缓存的数据始终缓存在回写式缓存中 即我假设