具体是什么将 x86 缓存行标记为脏 - 任何写入,或者是否需要显式更改?

2024-01-05

这个问题是具体来说针对现代 x86-64 缓存一致性架构 - 我很高兴答案在其他 CPU 上可能有所不同。

如果我写入内存,MESI协议要求首先将缓存行读入缓存,然后在缓存中修改(该值被写入缓存行,然后标记为脏)。在较旧的直写式微架构中,这将触发缓存行被刷新,在回写下,刷新缓存行可能会延迟一段时间,并且在两种机制下都可能发生一些写入组合(更有可能使用回写) 。我知道它如何与访问同一数据缓存行的其他核心交互 - 缓存监听等。

我的问题是,如果存储与缓存中已有的值精确匹配,如果没有任何一位被翻转,任何英特尔微架构是否会注意到这一点并且NOT将行标记为脏,从而可能避免将该行标记为独占,以及在某个时刻随之而来的写回内存开销?

当我对更多的循环进行矢量化时,我的矢量化操作组合原语不会显式检查值的变化,并且在 CPU/ALU 中这样做似乎很浪费,但我想知道底层缓存电路是否可以在没有显式编码的情况下做到这一点(例如存储微操作或缓存逻辑本身)。随着多个核心之间的共享内存带宽变得越来越成为资源瓶颈,这似乎是一种越来越有用的优化(例如,对同一内存缓冲区重复清零 - 如果这些值已经被读取,我们不会重新从 RAM 中读取这些值)在缓存中,但强制写回相同的值似乎很浪费)。写回缓存本身就是对此类问题的承认。

我可以礼貌地要求保留“理论上”或“这真的不重要”的答案吗 - 我知道内存模型是如何工作的,我正在寻找的是关于如何写入相同值的硬事实(而不是避免存储)将影响内存总线的争用,您可以安全地假设一台机器运行多个工作负载,这些工作负载几乎总是受到内存带宽的限制。另一方面,对芯片不这样做的确切原因的解释(我悲观地假设它们不这样做)将具有启发性......

Update: 这里有一些符合预期的答案https://softwareengineering.stackexchange.com/questions/302705/are-there-cpus-that-perform-this-possible-l1-cache-write-optimization https://softwareengineering.stackexchange.com/questions/302705/are-there-cpus-that-perform-this-possible-l1-cache-write-optimization但仍然有很多猜测“这一定很困难,因为它还没有完成”,并说如何在主 CPU 核心中执行此操作会很昂贵(但我仍然想知道为什么它不能成为实际缓存逻辑的一部分本身)。

更新(2020):Travis Downs 已经找到了硬件商店消除的证据,但似乎仅限于零,并且仅限于数据丢失 L1 和 L2 的情况,即便如此,也并非在所有情况下都如此。 强烈推荐他的文章,因为它更详细......https://travisdowns.github.io/blog/2020/05/13/intel-zero-opt.html https://travisdowns.github.io/blog/2020/05/13/intel-zero-opt.html

更新(2021):Travis Downs 现在发现了证据,表明这种零存储优化最近已在微代码中被禁用......更多详细信息来自来源本人https://travisdowns.github.io/blog/2021/06/17/rip-zero-opt.html https://travisdowns.github.io/blog/2021/06/17/rip-zero-opt.html


现在nox86(或任何其他 ISA,据我所知)的实现支持优化静默存储。

对此已有学术研究,甚至有一项关于“消除共享内存缓存一致性协议中静默存储失效传播”的专利。 (谷歌搜索'“静默存储”缓存' https://www.google.com/search?q=%22silent+store%22+cache如果您有兴趣了解更多。)

对于 x86,这会干扰 MONITOR/MWAIT;一些用户可能希望监视线程在静默存储上唤醒(可以避免失效并添加“触及”一致性消息)。 (目前 MONITOR/MWAIT 具有特权,但将来可能会改变。)

同样,这可能会干扰事务内存的一些巧妙使用。如果内存位置用作保护以避免显式加载其他内存位置,或者在支持此类的体系结构中(例如在 AMD 的高级同步工具中),则从读取集中删除受保护的内存位置。

(硬件锁消除是静默 ABA 存储消除的一种非常受限的实现。它的实现优点是显式请求检查值一致性。)

在性能影响/设计复杂性方面还存在实施问题。这将禁止避免读取所有权(除非静默存储消除仅在缓存行已经存在于共享状态时才处于活动状态),尽管目前还没有实现读取所有权避免。

对静默存储的特殊处理也会使内存一致性模型(可能尤其是 x86 相对强大的模型)的实现变得复杂。这也可能会增加因推测一致性失败而进行回滚的频率。如果静默存储仅支持 L1-present 线路,则时间窗口将非常小并且回滚极其稀有的;存储到 L3 或内存中的缓存行可能会将频率增加到非常罕见,这可能会使其成为一个值得注意的问题。

高速缓存行粒度上的静默也比访问级别上的静默少见,因此避免的失效数量会更少。

额外的缓存带宽也是一个问题。目前,英特尔仅在 L1 缓存上使用奇偶校验,以避免小量写入时需要读取-修改-写入。要求every写入以进行读取以检测静默存储将具有明显的性能和功耗影响。 (这样读 可以仅限于共享缓存行并机会主义地执行,利用没有完全缓存访问利用率的周期,但这仍然会产生功耗。)这也意味着如果已经存在读-修改-写支持,则此成本将会下降。 L1 ECC 支持(该功能会让某些用户满意)。

我对静默存储消除了解不多,因此可能还有其他问题(和解决方法)。

随着性能改进的许多唾手可得的成果被采取,更困难、更少益处和更不通用的优化变得更有吸引力。由于静默存储优化随着核心间通信的增加而变得更加重要,并且随着更多核心被用来处理单个任务,核心间通信也会增加,因此这种价值似乎可能会增加。

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

具体是什么将 x86 缓存行标记为脏 - 任何写入,或者是否需要显式更改? 的相关文章

  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • 为什么 printf 使用浮点和整数格式说明符打印随机值

    我在64位机器上写了一个简单的代码 int main printf d 2 443 所以 这就是编译器的行为方式 它将识别第二个参数为双精度型 因此它将在堆栈上压入 8 个字节 或者可能只是在调用之间使用寄存器来访问变量 d需要 4 字节整
  • 分支预测器和分支目标缓冲区如何共存?

    我的问题是它们如何在现代 CPU 架构中共存并协同工作 你把它稍微颠倒了 每次获取时 您都会索引到分支预测器 它会告诉您刚刚收到的指令是否will be解码为已采取的分支 如果没有 则获取下一个连续地址 但是 如果您的分支预测器说它将是一个
  • 整数溢出问题

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

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw
  • Grub 和进入实模式(低级汇编语言编程)

    我一直在开发一个玩具操作系统 并一直使用 grub 作为我的引导加载程序 最近尝试使用 VGA 时 我发现无法使用硬件中断 我发现这是因为我被 grub 置于保护模式 有人知道如何在不删除 grub 的情况下回到实模式吗 如果您使用 GRU
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • 标志寄存器中保留/未定义位的用途是什么?

    在 Z80 8080 8085 和 8086 处理器的标志寄存器中 被记录为 保留 或 未定义 的位 1 3 5 的用途是什么 这些位未使用 也就是说 没有指令明确地将它们设置为任何值 设计人员认为 5 6 个标志就足够了 他们只是将标志寄
  • PAE(物理地址扩展)如何实现大于4GB的地址空间?

    维基百科文章的摘录物理地址扩展 http en wikipedia org wiki Physical Address Extension x86 处理器硬件架构通过用于选择附加内存的附加地址线进行了增强 因此物理地址大小从 32 位增加到
  • 当 mov 指令导致页面错误并且在 x86 上禁用中断时会发生什么?

    我最近在自定义 Linux 内核 2 6 31 5 x86 驱动程序中遇到一个问题 其中 copy to user 会定期不将任何字节复制到用户空间 它将返回传递给它的字节数 表明它没有复制任何内容 经过代码检查 我们发现代码在调用 cop
  • 如何有效地扫描每次迭代交替的 2 位掩码

    给定 2 个位掩码 应交替访问 0 1 0 1 我尝试获得运行时高效的解决方案 但找不到比以下示例更好的方法 uint32 t mask 2 uint8 t mask index 0 uint32 t f tzcnt u32 mask ma
  • 从 DX:AX 寄存器转移到单个 32 位寄存器

    我在添加 16 位乘法的乘积时遇到问题 我想将一年 例如 2015 年 乘以 365 为此 我 mov dx 0 to clear the register mov ax cx cx holds the year such as 2015
  • 在 x86 程序集中打印寄存器值的简单方法

    我需要在 8086 Assembly 中编写一个程序 接收来自用户的数据 进行一些数学计算并在屏幕上打印答案 我已经编写了程序的所有部分并且一切正常 但我不知道如何打印号码显示到屏幕上 在我所有计算结束时 答案是 AX 它被视为无符号 16
  • 是否有适用于双打 (__m128d) 的 Move (_mm_move_ss) 和 Set (_mm_set_ss) 内在函数?

    多年来 我有几次看到 in 中的内在函数float参数被转换为 m128使用以下代码 m128 b mm move ss m mm set ss a 例如 void MyFunction float y m128 a mm move ss
  • 比“add esp, 4”更小的指令

    又是我 我的程序中有很多 add esp 4 我正在尝试减小它的大小 是否有任何更小的指令可以替代 add esp 4 pop edx 或者您不介意破坏的任何其他整数寄存器 这就是现代编译器实际上所做的 https stackoverflo
  • 为什么 mov %ax, %ds 汇编+反汇编为 mov %eax,%ds,与原来不一致?

    test S text global start start xor ax ax mov ax ds mov ax ss mov ax es mov ax fs mov ax gs 我通过这样做得到了反汇编代码文件 x86 64 elf g
  • 如何构建gcc multilib工具链?

    我正在尝试在新安装的 ubuntu 14 04 的 AMD64 版本上构建 gcc multilib 工具链 它只有 x86 64 gcc 和 g 安装 没有 multilib 支持 我的配置行是 configure disable che
  • 32位进程在64位操作系统上可以访问多少内存?

    在 Windows 上 正常情况下 32 位进程只能访问 2GB RAM 或通过 boot ini 文件中的特殊开关访问 3GB 在 64 位操作系统上运行 32 位进程时 有多少可用内存 是否有任何特殊的开关或设置可以改变这种情况 默认
  • 如何阅读英特尔操作码符号

    我正在阅读一些引用的材料Intel vol 2 SDM x86 手册 https www intel com content www us en developer articles technical intel sdm html关于汇编

随机推荐

  • Python:“打破”外循环

    在下面的Python代码中 narg len sys argv print length arg narg if narg 1 print Usage input filename nelements nintervals break I
  • 更改 Rails 会话 cookie 域而不注销用户

    我正在使用 Rails 4 2 2 带有 Devise 3 4 1 并将 cookie store 域从 www boundless dev 更改为 boundless dev 以便在所有子域之间共享相同的会话 单点登录 Boundless
  • 我应该在 Heroku Cedar 上使用 Thin 还是 Unicorn

    我最近将我的应用程序 升级 到了 Heroku 上的 cedar 平台 默认情况下 我正在使用thin作为网络服务器 但我一直想用unicorn为了并发性并让我的动力美元去爸爸 但我担心使用 Thin 以外的东西会遇到一些问题 有人对这个决
  • UICollectionView 类似报纸的布局

    UICollectionView 是否可以灵活地动态呈现如下所示的界面 Newsify for iPhone 或者只能渲染预定义的静态布局 我想根据图像尺寸 高x宽 进行布局 比如小图像的小网格和大图像的大网格 所有这些都是在运行时根据我从
  • 导入 com.lowagie.database.DatabaseConnection 时出错

    我完成了第 1 章练习 现在转到第 2 章 我正在进行第一次 DatabaseTest 练习 但在导入语句中遇到错误 import com lowagie database DatabaseConnection and import com
  • 更新 Metal 中 MTLBuffer 的内容

    我需要帮助来替换 a 的内容MTL缓冲区无需创建新的 两种情况下的内容都是浮点数组 let vector Float 0 1 2 3 4 5 6 7 8 9 let byteLength arr1 count MemoryLayout
  • Vuejs 变异对象作为 prop 传递

    如果我将一个对象作为 prop 传递 引用 可以改变 prop 中的值吗 我正在开发一个网络应用程序 需要将大量值传递给组件 并且我正在尝试找到将值传递给组件并返回给父级的最佳方法 从我读到的所有内容来看 改变 prop 是错误的做法 因为
  • android 保存到SD卡

    大家好 我有一个小问题 我有这个代码可以将图像保存到 SD 卡 public String SDSave View arg0 TODO Auto generated method stub OutputStream outStream nu
  • 如何禁用点击文本字段时出现的键盘,iOS?

    我有一个文本字段 当用户按下它时我需要显示自定义选择器 选择器显示正常 但问题是键盘出现在底部 我不希望这样 这是一个 iPad 项目 我正在尝试从我的 iPhone 转换它 在 iPhone 上 这种方法效果很好 并且键盘始终是隐藏的 我
  • 如何建立快速可靠的 S3 到 EC2 连接 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 EC2 提供了一种非常方便的 按需可扩展的机制来执行可分布式 可并行 的进程 而 S3 提供了可靠的存储服务 我尝试使用 EC2 节点进行 ETL 和
  • 在 Django 中使用 ContentType 过滤 2 个模型

    我有 2 个配置文件模型 我正在创建一个 与会者 对象 如何仅在 2 个配置文件之间进行过滤 class Profile1 models Model user models ForeignKey User null True unique
  • 在 R 中引用行号

    如何引用观察的行号 例如 如果您有一个data frame称为 数据 并想要创建一个变量data rownumber等于每个观察的行号 如果不使用循环 您将如何做到这一点 这些默认情况下显示为rownames当你创建一个data frame
  • Windows Phone 8.1 C# 应用程序:仅在发布模式下的真实设备上发生严重崩溃 (ExecutionEngineException)

    想象一下以下结构类型 public struct Token IDictionary
  • 使用vba在word文档中查找斜体字体

    随着Find功能 Ctrl F 我可以从文档中搜索并选择所有斜体字 这个用vba怎么实现呢 我尝试了宏记录器 但我得到的代码不起作用 Sub Makro1 Makro1 Makro Makro aufgezeichnet am 16 06
  • Quarkus Keycloak 自定义授权

    我尝试在 quarkus 中进行一些 websocket 身份验证 我目前有使用启用的身份验证的休息端点 我使用 keyclock 进行身份验证 并使用 vert x 与 websocket 进行双向连接 也在 github 线程中发布此问
  • Tmux 边框显示为 x q 而不是线条?

    我无法让 tmux 显示边框线 它们是用 x 和 q 创建的 它是一个 debian squeeze 服务器 区域设置设置为 en US UTF8 我也尝试添加 instructs tmux to expect UTF 8 sequence
  • 使用状态和定时器进行处理

    在 Beam Dataflow 运行程序中使用状态处理和计时器 从 v2 1 0 开始 是否有任何准则或限制 例如状态大小或更新频率的限制等 候选流管道将广泛使用状态和计时器来表示用户会话状态 并使用 Bigtable 作为持久存储 以下是
  • 使用 NSConnection 连接到“www.google.com”时出现错误

    使用连接到 www google com 时出现错误NSConnection 我找不到原因 任何帮助将不胜感激 NSString urkString www google com NSURL url NSURL URLWithString
  • 如何使用 C/C++ 预处理器生成一系列随机数

    我想生成一系列随机数C预处理器 并将它们存储在变量中以供我的程序使用 目标 我想在每次构建程序时生成一组 独特 的随机数 存储随机数的变量的一小部分将被有意义的 即非随机 数字覆盖 我希望黑客不可能通过调试程序或比较多个版本来区分有意义的数
  • 具体是什么将 x86 缓存行标记为脏 - 任何写入,或者是否需要显式更改?

    这个问题是具体来说针对现代 x86 64 缓存一致性架构 我很高兴答案在其他 CPU 上可能有所不同 如果我写入内存 MESI协议要求首先将缓存行读入缓存 然后在缓存中修改 该值被写入缓存行 然后标记为脏 在较旧的直写式微架构中 这将触发缓