如果我不使用栅栏,一个核心需要多长时间才能看到另一个核心的写入?

2023-11-26

我一直在尝试用谷歌搜索我的问题,但老实说我不知道​​如何简洁地陈述这个问题。

假设我在多核英特尔系统中有两个线程。这些线程在同一个 NUMA 节点上运行。假设线程 1 向 X 写入一次,然后偶尔向前读取它。进一步假设线程 2 连续读取 X。如果我不使用内存栅栏,线程 1 写入 X 和线程 2 看到更新值之间需要多长时间?

据我所知,X 的写入将进入存储缓冲区,然后从那里进入高速缓存,此时 MESIF 将启动,线程 2 将通过 QPI 查看更新后的值。 (或者至少这是我收集到的)。我认为存储缓冲区将被写入存储栅栏上的缓存,或者如果需要重用该存储缓冲区条目,但我不知道存储缓冲区被分配给写入。

最终,我试图为自己回答的问题是,在一个正在执行其他工作的相当复杂的应用程序中,线程 2 是否有可能在几秒钟内看不到线程 1 的写入。


内存屏障不会让其他线程看到您的存储any faster.(除了阻止以后的加载可能会稍微减少提交缓冲存储的争用。)

The store buffer always tries to commit retired (known non-speculative) stores to L1d cache as fast as possible. Cache is coherent1, so that makes them globally visible because of MESI/MESIF/MOESI. The store buffer is not designed as a proper cache or write-combining buffer (although it can combine back-to-back stores to the same cache line), so it needs to empty itself to make room for new stores. Unlike a cache, it wants to keep itself empty, not full.

Note 1:不只是x86;任何 ISA 的所有多核系统(我们可以跨其核心运行 Linux 的单个实例)都必然是缓存一致的; Linux依赖于volatile其手工滚动原子使数据可见。类似地,C++std::atomic加载/存储操作mo_relaxed只是普通的 asm 加载和存储在所有普通 CPU 上,依赖硬件来实现内核之间的可见性,而不是手动刷新。何时在多线程中使用 易失性?解释说。有一些集群或混合微控制器+DSP ARM 板具有非一致性共享内存,但我们不会跨单独的一致性域运行同一进程的线程。相反,您可以在每个集群节点上运行单独的操作系统实例。我不知道有任何 C++ 实现atomic<T>加载/存储包括手动冲洗指令。 (如果有的话请告诉我。)


栅栏/屏障的工作原理是让当前线程等待

...直到通过正常机制发生所需的任何可见性。

完整屏障的简单实现(mfence or a locked 操作)的目的是停止管道,直到存储缓冲区耗尽,但高性能实现可以做得更好,并允许与内存顺序限制分开的乱序执行。

(很遗憾天湖的mfence确实完全阻止乱序执行,修复涉及从 WC 内存加载 NT 的模糊 SKL079 勘误表。但lock add or xchg或任何仅阻止稍后从读取 L1d 或存储缓冲区加载的内容,直到屏障到达存储缓冲区的末尾。和mfence在早期的 CPU 上可能也没有这个问题。)


一般来说,在非 x86 架构上(对于较弱的内存屏障有显式的 asm 指令,例如仅限 StoreStore 围栏不关心负载),原理是相同的:阻止它需要阻止的任何操作,直到该核心完成任何类型的早期操作。

Related:

  • 全局不可见加载指令讨论负载变得全局可见意味着什么/负载数据来自哪里。

  • 内存屏障是否确保缓存一致性已完成?

  • 内存屏障是否既充当标记又充当指令?

  • 何时在多线程中使用 易失性?- 基本上从不,这只是你自己的一种方式std::atomic<T> with std::memory_order_relaxed因为缓存一致性。

  • 推测执行的 CPU 分支是否可以包含访问 RAM 的操作码?- 什么是存储缓冲区以及它们存在的原因。


最终,我试图为自己回答的问题是线程 2 是否有可能在几秒钟内看不到线程 1 的写入

不,最坏情况的延迟可能类似于存储缓冲区长度(Skylake 上有 56 个条目,而 BDW 中有 42 个条目)乘以缓存未命中延迟,因为 x86 的强内存模型(无 StoreStore 重新排序)要求存储按顺序提交。但是多个缓存行的 RFO 可以同时运行,因此最大延迟可能是其 1/5(保守估计:有 10 个行填充缓冲区)。飞行中的负载(或来自其他核心)也可能存在争用,但我们只想要一个数量级的粗略数字。

假设 RFO 延迟(DRAM 或来自另一个内核)在 3GHz CPU 上为 300 个时钟周期(基本上是弥补的)。所以一个最坏的情况下延迟商店在全球范围内可见可能是这样的300 * 56 / 5= 3360 个核心时钟周期。所以在一个数量级内,最坏情况约为 1 微秒在我们假设的 3GHz CPU 上。 (CPU 频率相互抵消,因此以纳秒为单位估计 RFO 延迟会更有用)。

就在那时all您的商店需要等待很长时间才能收到 RFO,因为它们all到未缓存或由其他核心拥有的位置。并且它们都不是连续的同一缓存行,因此它们都不能合并到存储缓冲区中。所以通常你会期望它会快得多。

我认为没有任何合理的机制可以让它花费一百微秒,更不用说一整秒了。

如果您的所有存储都是缓存行,而其他内核都在竞争访问同一行,则您的 RFO 可能需要比正常情况更长的时间,因此可能需要数十微秒,甚至可能是一百微秒。但这种绝对最坏的情况不会偶然发生。

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

如果我不使用栅栏,一个核心需要多长时间才能看到另一个核心的写入? 的相关文章

随机推荐

  • 运算符 = C++ 中使用 Const 变量重载

    我想知道你们是否可以帮助我 这是我的 h Class Doctor const string name public Doctor Doctor string name Doctor Doctor operator const Doctor
  • UICollection View 与 SDWebImage 的滚动滞后

    背景 我搜索过SO和苹果论坛 很多人谈论带有图像的集合视图单元的性能 他们中的大多数人表示 自从在主线程中加载图像以来 滚动出现了滞后 通过使用SDWebImage 图像应该在单独的线程中加载 不过 iPad 模拟器中仅在横向模式下存在延迟
  • Django 教程,获取:reverse() 的 /admin/ 参数处的 TypeError 必须是序列

    我正在学习 1 8 版本的 django 教程 但遇到了一个错误 我被困住了 似乎无法弄清楚 我以为我已经完全按照教程进行操作了 我设置了以下树 dj project init py init pyc settings py setting
  • 在 R Plotly 中使用曲面椭圆绘制 Ellipse3d

    与这里的问题类似 但这并没有给我确切的需要 我无法弄清楚 在 R 中绘制 ellipse3d 的图 我想在绘图中重新创建 rgl 的 ellipse3d 和表面椭球体 我知道有一个答案允许绘制椭圆体 但作为单独的不透明标记 我需要将其作为稍
  • 具有更高建议缩放比例的显示器上的 RDLC 问题

    我的 WPF 应用程序使用的是 net Framework 4 8 并且 RDLC 有两种用法 第一个是完全获取的 ReportViewer 它使用来自 postgres 的 DataTable 第二个只是一个 LocalReport 其中
  • 如何在不强制实现的情况下找到惰性序列的长度?

    我目前正在阅读 O reilly Clojure 编程书 其中关于惰性序列的部分提到了以下内容 惰性序列有可能 尽管非常罕见 知道其长度 因此将其作为计数结果返回 而不了解其内容 我的问题是 这是如何做到的以及为什么如此罕见 不幸的是 本书
  • 在java中访问网络共享文件夹(位于Windows或Linux中)的推荐方式是什么

    各位 请原谅我对Linux不熟悉 我正在尝试读取位于 Windows 或 Linux 系统中的网络共享文件夹的所有文件 目前我只是通过下面的代码使其适用于 Windows 的情况 networkShareFolder 10 50 90 18
  • Android SDK Windows 无法执行 Android.bat

    标题可能听起来有点 无聊 但我向你保证事实并非如此 我完全了解 cmd 中 90 的 systax 命令 我可以通过 adb 安装和卸载 apk 但是这个特殊的问题总是让我退缩 我已经在 Android SDK 上工作了一周或更长时间了 并
  • 显式布尔运算符错误

    我得到了编译器错误 C2071当我尝试实施explicit operator bool class C public explicit operator bool const return this 为什么 我怎么解决这个问题 我正在使用
  • Flutter:在 ListView 中添加步进器时不滚动

    我有 ListView 其中包含 1 横幅图片 2 带有一些文本的容器 3 带有更多文本的容器 4 容器由Stepper组成 当我在点击步进器区域时尝试滚动时 我无法滚动 甚至步进器的最后一步也会超出屏幕 添加代码 import packa
  • 在 Python 的 NLTK 中从自定义文本生成随机句子?

    我在 Python 下使用 NLTK 时遇到问题 特别是 generate 方法 生成 自身 长度 100 打印使用 trigram 语言模型生成的随机文本 参数 length int The length of text to gener
  • 验证用户输入?

    我对某事感到非常困惑 想知道是否有人可以解释 在 PHP 中 我验证用户输入 因此 htmlentitiies mysql real escape string 在插入数据库之前使用 而不是在所有内容上使用 因为我更喜欢尽可能使用正则表达式
  • 带接口的 Angular 6 服务

    我正在使用 Angular 构建一个应用程序 6 0 7 我正在尝试使用新的服务创建服务 Injectable providedIn root 但是如何使用接口进行注入呢 问题 我有2个服务 认证服务 and 会话存储 service 我想
  • 内联限定符源于原型还是定义?

    我对标准中的这一点不太确定 假设我有三个这样的文件 foo h include
  • 如何强制 Postgresql 用户使用密码登录

    我所做的一切都在我的local机 Mac 操作系统 安装postgresql后 我创建了一个名为pote的用户和密码 然后创建了一个名为poems的数据库 该数据库的所有者是pote 我好奇的是我可以不用密码登录诗人的诗歌 命令是psql
  • 您是否将单元测试与集成测试分开? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我只是想知道是否还有其他人
  • Facebook 图 api 搜索结果取决于位置?

    我尝试使用图形搜索 API 获取结果 我注意到在我的计算机 阿根廷 中执行的结果与在服务器 法国 中运行时的结果不同 是这样的吗 如何强制指定搜索位置 谢谢 Sascha Galley 我还找到了另一种简单的方法 只需添加 locale e
  • 为什么 minmax(0, 1fr) 对于长元素有效,而 1fr 则无效?

    所以我有这个网格 div p 1000 characters long p div Inside p有一个超长的字符串 没有空格 divs 是具有固定尺寸的占位符 这会产生以上结果 display grid grid auto flow c
  • 在 ajax 数组中使用 jQuery .serialize() 将 PHP $_POST 作为变量传递?

    这是我用来将表单详细信息发送到 php 函数的 jQuery 代码 jQuery document ready function jQuery submit click function var str ajaxForms serializ
  • 如果我不使用栅栏,一个核心需要多长时间才能看到另一个核心的写入?

    我一直在尝试用谷歌搜索我的问题 但老实说我不知道 如何简洁地陈述这个问题 假设我在多核英特尔系统中有两个线程 这些线程在同一个 NUMA 节点上运行 假设线程 1 向 X 写入一次 然后偶尔向前读取它 进一步假设线程 2 连续读取 X 如果