- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在总存储顺序(TSO)内存一致性模型下,x86 CPU将具有一个写缓冲区来缓冲写请求,并可以处理来自写缓冲区的重新排序的读请求。它说写缓冲区中的写请求将退出并以FIFO顺序向高速缓存层次结构发出,这与程序顺序相同。
我很好奇:
为了满足从写缓冲区发出的写请求,L1高速缓存控制器是否处理写请求,完成写请求的高速缓存一致性并将数据按与发布顺序相同的顺序插入L1高速缓存中?
最佳答案
您的用语不寻常。您说“完成缓存一致性”;实际发生的情况是,内核必须先拥有(专有)缓存行的所有权,然后才能对其进行修改。在修改发生的瞬间/周期,它成为高速缓存一致性协议中所有参与者共享的内存内容视图的一部分。
因此,是的,您可以“完成缓存一致性” =在商店甚至可以进入缓存并变得全局可见之前获得独占所有权=可用于共享该缓存行的请求。缓存始终保持一致性(这是MESI的重点),而不是保持不同步,然后等待一致性。我认为您的困惑源自您的思维模式与现实不符。
(弱排序的体系结构可能会让人费解,例如,并非所有内核都以相同的顺序从其他两个内核看到存储;这可以由private store-forwarding between SMT threads on one physical core letting another logical core see a store ahead of commit to L1d = global visibility发生。)
我想您知道其中一些内容,但让我从基础开始。
每个核心中的L1缓存参与缓存一致性协议,该协议可使其缓存与一致性域中的其他缓存保持一致(例如L2和L3,以及其他核心中的L1,但GPU内部不包含video-RAM缓存)。
从L1缓存(or from the store buffer或不可缓存的RAM或MMIO)读取数据时,负载在全局范围内可见。 MFENCE
可以迫使他们等待更早的存储在全局范围内可见,然后再将L1采样到avoid StoreLoad reordering。
当存储将数据提交到L1缓存时,该存储将在全局范围内可见。可能发生的条件是:
执行完毕:数据+地址在存储缓冲区条目中。 (即,一旦输入准备就绪,将在适当的端口上执行存储地址和存储数据,将地址和数据写入存储缓冲区,也就是英特尔CPU上的内存顺序缓冲区)。
它是retired来自核心的乱序部分,因此被认为是非推测性的。在退休之前,我们不知道it and all preceding instructions won't fault,也不知道它没有出现分支错误预测或其他错误推测的阴影。
退休只能在完成执行后发生,但与对L1d的承诺无关。存储缓冲区可以继续跟踪非推测性存储,即使ROB(无序执行ReOrder Buffer)忘记了存储指令后,也肯定会最终发生。
先前所有的加载/存储/围栏已经是全局可见的(由于x86的内存排序规则)。这不包括操作较差的操作(NT商店);其他负载/存储可以通过它们。
在当前内核的L1d高速缓存中,高速缓存行处于MESI / MESIF / MOESI高速缓存一致性协议的“排他”或“已修改”状态。如果RFO(所有权读取)在高速缓存的外部级别遇到高速缓存未命中,或者与其他也希望以独占方式访问以写入或原子地RMW的高速缓存行竞争的内核,则可能会花费很长时间。
有关允许的状态转换的图和详细信息,请参见Wikipedia的MESI article。关键点是,在确保没有其他缓存包含该行的情况下,仅允许内核修改其缓存行的副本即可实现一致性,因此不可能存在同一行的两个冲突副本。
英特尔CPU实际上使用MESIF,而AMD CPU实际上使用MOESI允许高速缓存->高速缓存数据传输脏数据,而不是像基本MESI协议所要求的那样写回到共享的外部高速缓存。
另请注意,现代Intel设计(在Skylake-AVX512之前)实现使用large shared inclusive L3 cache as a backstop for cache-coherency,因此探听请求实际上不必广播到所有内核。他们只检查L3标签(其中包含额外的元数据以跟踪哪个内核在缓存什么。
英特尔的L3即使在内部缓存处于“排他”或“已修改”状态且在L3中无效的行中也包含标签。参见this paper for more details of a simplified version of what Intel does)。
也相关:I wrote an answer recently about why we have small/fast L1 + larger L2/L3, instead of one big cache,包括一些指向其他与缓存相关的内容的链接。
回到实际问题:
是的,存储按照程序顺序提交到L1,因为这是x86要求它们成为全局可见的顺序。 L1提交命令与全局可见性命令相同。
与其说“完成缓存的一致性”,不如说“获取缓存行的所有权”。这涉及使用缓存一致性协议与其他缓存进行通信,因此我想您可能是说“使用缓存一致性协议来获得独占所有权”。
MESI Wiki文章的memory ordering部分指出,存储队列中的缓冲存储通常与无序执行分开。
存储缓冲区将提交到L1d的提交从OoO执行退役中解耦。与常规无序窗口大小相比,这可能会隐藏更多的存储延迟。但是,即使有中断到达,退休存储区也必须最终(以正确的顺序)发生,因此允许大量退休但没有提交的存储区会增加中断等待时间。
存储缓冲区尝试尽快将已退休的存储区提交到L1d,但受内存排序规则的限制。 (即其他核心很快就会看到存储;您不需要围墙就可以刷新存储缓冲区,除非您需要当前线程等待该事件发生,然后再加载到该线程中,例如顺序一致的存储。)
在顺序较弱的ISA上,较早的存储仍在等待高速缓存未命中时,以后的存储可以提交到L1d。 (但是您仍然需要一个内存顺序缓冲区,以保留程序顺序中单个核心运行指令的错觉。)
存储缓冲区可能一次有多个未命中的高速缓存未命中,因为即使在顺序严格的x86上,它也可以在该存储区是缓冲区中最旧的存储区之前为该高速缓存行发送RFO。
关于x86 - L1高速缓存 Controller 的顺序以处理来自CPU的内存请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38034701/
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 3 年前。 Improve th
作为练习,我正在尝试使用 Thread.sleep 作为计时器并使用 JMF 作为声音来使用 Java 创建一个节拍器。它运行良好,但出于某种原因,JMF 似乎只能以每分钟最多 207 拍的速度播放声
有谁知道对用户浏览器进行基准测试的快速方法?它不需要那么准确。 我开始在我们的软件平台中使用 Javascript 执行越来越多的密集型任务,我担心性能在旧浏览器上会成为一个问题,所以我想要的是我可以
我的数据看起来像每帧 1000 万个数值(实数 + 二进制)(想想数组,即数组的一行中有 1000 万个元素)并且大约有 100 帧/秒。一种时间序列。 我的挑战是: (1) 存储——数据量 (2)
在使用 Android 时,我丢失了传入 USB 数据流上的数据,而在 Windows 中读取同一设备/流时我不会丢失这些数据。 (我知道 Android 不是实时操作系统,但 Windows 也不是
在我目前正在做的一个C#项目中,我们试图计算网络上大量文件的MD5(当前pot是270万,客户端pot可能超过1000万)。随着我们处理的文件数量的增加,速度成为问题。 我们这样做的原因是为了验证文件
我一直在尝试使用 XSLT 在最有效的时间内从 XML 文档获取 CSV 数据。以下是我的示例 XML Raagu Hoskote
如果标题听起来令人困惑,我很抱歉,如果您在这段描述后有更好的想法,请随时提出建议。 简而言之,我在 Linux 上使用 PHP 以及以下假设的文件/代码: job.php: if(setting_ge
对最多 1000 万个 7 位数字进行排序。约束条件:1M RAM,高速。几秒就好。 [编辑:来自提问者的评论:输入值不同] 使用位图数据结构可以很好地解决这个问题。 这意味着我需要一个字符串,它的长
我是一名优秀的程序员,十分优秀!