当前位置: 首页 > 知识库问答 >
问题:

缓存一致性文献通常只引用存储缓冲区,而不引用读取缓冲区。然而,不知何故,两者都需要?

庞修贤
2023-03-14

在阅读一致性模型(即x86 TSO)时,作者通常会求助于有大量CPU、相关存储缓冲区和专用缓存的模型。

如果我的理解是正确的,那么存储缓冲区可以描述为队列,CPU可以在队列中放置他们想要提交到内存的任何存储指令。正如名称所述,它们是缓冲区。

但是当我阅读这些论文时,他们倾向于谈论负载和存储的交互,诸如“较晚的负载可以通过较早的存储”之类的语句有点令人困惑,因为他们似乎在谈论存储缓冲区将同时具有负载和存储,而不是——对吗?

因此,还必须有一个他们没有(至少明确地)谈论的加载存储。此外,这两个必须以某种方式同步,以便两者都知道何时可以从内存加载并提交到内存——或者我错过了什么?

有人能对这件事多解释一下吗?

编辑:

让我们看看“内存一致性和高速缓存一致性入门”中的一段:

为了理解TSO中原子RMW的实现,我们将RMW视为紧接着存储的加载。由于TSO的排序规则,RMW的加载部分无法通过早期加载。起初,RMW的加载部分可能会通过写入缓冲区中的早期存储,但这是不合法的。如果RMW的加载部分通过较早的存储,那么RMW的存储部分也必须通过较早的存储,因为RMW是原子对。但由于TSO中不允许存储相互传递,RMW的加载部分也不能传递较早的存储

更具体地说,

由于TSO的排序规则,RMW的加载部分无法通过早期加载。一开始,RMW的加载部分可能会通过写入缓冲区中的早期存储

所以他们指的是写入缓冲区中相互交叉的加载/存储(我假设这与存储缓冲区相同?)

谢谢

共有1个答案

潘刚洁
2023-03-14

是,写入缓冲区=存储缓冲区。

他们讨论的是,如果一个原子RMW被拆分为一个单独的加载和存储,并且存储缓冲区延迟了另一个存储(到一个单独的地址),那么它是在加载之后,但仍然在存储之前。

显然,这将使其成为非原子的,并且违反了所有x86原子RMW操作也是完全屏障的要求。(前缀lock也暗示了这一点。)

通常情况下,读卡器很难检测到这一点,但如果“单独地址”与原子RMW相邻,则例如,dword存储dword RMW可能会被另一个线程作为一个原子操作同时进行64位qword加载。

回复:标题问题:

加载缓冲区不会导致重新排序。他们等待尚未到达的数据;加载在读取数据时完成“执行”。

存储缓冲区是根本不同的;在数据在全球可见之前,它们会保存一段时间。

x86的TSO内存模型可以描述为存储缓冲区(具有存储转发)的顺序一致性。另请参阅x86 mfence和C内存屏障以及对该答案的评论,以了解更多关于以下事实的讨论:对于线程重新加载刚刚存储的数据的情况,仅允许StoreLoad重新排序是不够的,尤其是如果加载与最近的存储部分重叠,那么硬件会将存储缓冲区中的数据与L1d中的数据合并,以在存储全局可见之前完成加载。

还要注意的是,x86 CPU会推测性地对负载进行重新排序(至少英特尔会这样做),但为了保留无负载或负载存储区重新排序的TSO内存模型,会消除错误推测。因此,CPU必须跟踪负载与存储顺序。Intel将组合存储加载缓冲区跟踪结构称为“内存顺序缓冲区”(MOB)。请参阅Intel硬件上html" target="_blank">存储缓冲区的大小?存储缓冲区究竟是什么?更多信息。

 类似资料:
  • 我有一个二进制数据缓冲区,我想存储在协议缓冲区中。 在留档(https://developers.google.com/protocol-buffers/docs/proto#scalar)中,它说类型等价于C中的。我无法相信这一点,所以我不得不尝试它,是的,这似乎是这样... 本协议: 给出一个包含以下内容的消息定义: 公共setter/getter API如下所示: 当然,这不是在消息中存储二

  • 问题内容: 在编写用于OpenGL库的Matrix类时,我遇到了一个问题,即使用Java数组还是使用Buffer策略存储数据(JOGL为Matrix操作提供直接缓冲区复制)。为了对此进行分析,我编写了一个小型性能测试程序,该程序比较了Arrays vs Buffers和Direct Buffers上循环和批量操作的相对速度。 我想在这里与您分享我的结果(因为我发现它们很有趣)。请随时发表评论和/或

  • 纯JavaScript是Unicode友好的,但二进制数据却不是这样。 在处理TCP流或文件系统时,必须处理八位字节流。 Node提供了Buffer类,它提供了存储类似于整数数组的原始数据的实例,但对应于V8堆外部的原始内存分配。 Buffer类是一个全局类,可以在应用程序中访问而无需导入缓冲区模块。 创建缓冲区 节点缓冲区可以以多种方式构建。 Method 1 以下是创建10个八位字节的无启动缓

  • 我对openGL渲染很陌生,无论我做什么,深度深度都不起作用。我显然已经启用了深度测试(),并且我清除了每一帧的缓冲区。 但是 openGL 不断显示最后在其他人面前渲染的对象... 你可以在我的github上看到我的代码。这是两个相关的文件:主循环。我的主循环在,渲染在。 我正在使用java和lwjgl。

  • 我的目标是用扩展名解析协议缓冲区文件。pb。一串在Mac上使用自制软件下载Protobuff。运行protoc--版本,并具有libprotoc 3.1.0版本。 但当我运行Python时,它会说找不到模块。我改变了主意。pb文件名到\u pb2。py并在Python脚本中导入模块。 我正在使用谷歌文档,但仍然没有任何运气。我在编译Protobuf时也遇到了问题。so文件通过Python。我只是无

  • 我正在连载: 和反序列化: