繁体   English   中英

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

[英]If I don't use fences, how long could it take a core to see another core's writes?

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

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

我知道 X 的写入将进入存储缓冲区并从那里进入缓存,此时 MESIF 将启动,线程 2 将通过 QPI 看到更新的值。 (或者至少这是我收集到的)。 我假设存储缓冲区会在存储围栏上或如果需要重用该存储缓冲区条目时写入缓存,但我不知道存储缓冲区是否被分配给写入。

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

记忆障碍,不要让其他线程看到你的店更快。 (除了阻止以后的加载可以稍微减少提交缓冲存储的争用。)

存储缓冲区总是尝试尽快将退休(已知的非推测性)存储提交到 L1d 缓存。 缓存是一致的1 ,因此由于 MESI/MESIF/MOESI 使它们全局可见。 存储缓冲区不是设计为适当的缓存或写入组合缓冲区(尽管它可以将背靠背存储组合到同一缓存行),因此它需要清空自己为新存储腾出空间。 与缓存不同,它希望自己保持空,而不是满。

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


Fences/barriers 通过让当前线程等待来工作

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

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

(不幸的是, Skylake 的mfence确实完全阻止了乱序执行,以修复涉及来自 WC 内存的 NT 加载的模糊 SKL079 错误。但是lock addxchg或任何只会阻止稍后加载读取 L1d 或存储缓冲区,直到屏障到达存储缓冲区的mfence 。早期 CPU 上的mfence大概也没有这个问题。)


一般来说,在非 x86 架构上(对于较弱的内存屏障有显式的 asm 指令,比如只使用 StoreStore 栅栏而不关心负载),原理是一样的:阻塞任何需要阻塞的操作,直到这个内核完成了之前的任何操作类型。

有关的:


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

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

假设 RFO 延迟(DRAM 或来自另一个内核)是 3GHz CPU 上的 300 个时钟周期(基本构成)。 因此,存储变得全局可见的最坏情况延迟可能类似于300 * 56 / 5 = 3360 个核心时钟周期。 因此,在一个数量级内,我们假设的 3GHz CPU 上的最坏情况约为 1 微秒 (CPU 频率抵消,因此以纳秒为单位的 RFO 延迟估计会更有用)。

那时您的所有存储都需要等待很长时间才能获得 RFO,因为它们位于未缓存或由其他核心拥有的位置。 并且它们中没有一个是背靠背的同一个缓存行,因此没有一个可以在存储缓冲区中合并。 所以通常你会期望它快得多。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM