什么是真正的分享?
Posted
技术标签:
【中文标题】什么是真正的分享?【英文标题】:What is true sharing? 【发布时间】:2019-08-22 09:40:30 【问题描述】:在阅读this 问题时,我遇到了“虚假共享”和“真实共享”这两个词。我读过什么是虚假分享,但我在真正的分享上找不到任何东西。尽管在提到的问题中,该术语被描述为“建设性干扰”,但我仍然不明白它的含义。
【问题讨论】:
如果您在问题中重复基本部分作为引用,而不仅仅是链接,那就太好了。从链接的问题来来回回有点乏味。 【参考方案1】:这就是我从硬件设计角度对真共享和假共享的理解。如果我错了,请纠正我。
内核在访问变量时会加载一块内存,以减少内存访问时间。在多核系统中,这些“高速缓存行”之间的一致性将被保持。即便如此,缓存未命中仍可能由于多种原因而发生,其中两种原因是两种类型的数据共享造成的。
“真正的数据共享”,其中两个核心尝试访问和修改同一个字,导致另一个核心中的高速缓存行连续失效。 假设高速缓存行大小为 2 个字,核心 0 和核心 1 正在尝试修改地址 0x100。假设字节存储,2字缓存线大小意味着0x100~0x108将被加载到核心0和核心1的缓存中。现在当核心0修改0x100处的数据时,缓存线incore 1无效。当核心 1 修改 0x100 处的数据时,它必须使用核心 0 缓存中的数据更新其缓存行,并且核心 0 中的缓存行无效。之后它将写入 0x100。现在如果这发生在一个循环中,大量的带宽被浪费在缓存维护中。这是由于真正共享导致的缓存未命中,其中内核之间存在“真正共享”的数据字。
第二种是“假共享数据”,两个核心,试图访问和修改同一个缓存行内的两个不同的字,导致另一个核心的缓存行不断失效。以前面的例子,假设核心 0 想要修改 0x100,核心 2 想要修改 0x104。现在当核心 0 修改 0x100 处的数据时,核心 1 缓存行无效。当核心 1 修改 0x104 处的数据时,它必须使用核心 0 缓存中的数据更新其缓存行,并且核心 0 中的缓存行无效。之后它将写入 0x104。在循环中完成时,这也会导致性能损失。这里的性能损失是由于两个内核之间的“错误共享”数据造成的。
【讨论】:
【参考方案2】:真正的共享是一个内核访问已加载到单个缓存行中的多个附近的内存地址。第一次之后的每次访问都受益于缓存。
【讨论】:
而且两个不同的核心不会访问属于另一个核心的数据,不是吗? 好的,谢谢。所以问题是,一方面cache line应该尽可能的大,这样会有很多真正的共享和很少的cache miss,另一方面应该尽可能的小,所以会有很少的错误共享并且缓存行失效将需要更少的内存来重新获取。我说的对吗? 这不就是空间局部性原理吗? @YanB。缓存线大小还有其他(物理/电气)考虑因素。此外,如果您要访问范围内的每个字词,则缓存行的大小无关紧要。 @Jean-BaptisteYunès 是的。具有空间局部性的数据可以从访问它时发生的任何真正共享中获得性能优势【参考方案3】:据我理解,真共享是指多核频繁写入同一个共享变量的问题,而假共享是指向多个内核写入同一缓存中的不同变量。
在这两种情况下,缓存都必须经常失效才能加载最新版本,但真正的共享无法通过例如添加填充以确保两个变量位于不同的缓存行上。
参考资料:
https://inst.eecs.berkeley.edu/~cs61c/resources/su18_lec/Lecture20.pdf#page=56 http://thebeardsage.com/true-sharing-false-sharing-and-ping-ponging/ https://suif.stanford.edu/papers/anderson95/node2.html【讨论】:
以上是关于什么是真正的分享?的主要内容,如果未能解决你的问题,请参考以下文章