在阅读这篇问题时,我遇到了"false sharing"和"true sharing"这两个术语。我了解了什么是"false sharing",但是我找不到任何关于"true sharing"的信息。虽然在提到的问题中,该术语被描述为"constructive interference",但我仍然不理解它的含义。
在阅读这篇问题时,我遇到了"false sharing"和"true sharing"这两个术语。我了解了什么是"false sharing",但是我找不到任何关于"true sharing"的信息。虽然在提到的问题中,该术语被描述为"constructive interference",但我仍然不理解它的含义。
从硬件设计的角度来看,我对真实共享和误导性共享有了一些理解。如果我有误,请纠正我。
核心在访问变量时会加载一块内存,以减少内存访问时间。在多核系统中,需要维护这些“缓存行”之间的一致性。即使如此,由于各种原因可能会发生缓存未命中,其中两个原因是由数据的两种共享方式引起的。
所谓“真实共享”的数据是指两个核心尝试访问和修改同一个字,导致另一个核心中的缓存行不断失效。假设缓存行大小为2个字,核心0和核心1正在尝试修改地址0x100。假设是字节存储,2个字的缓存行大小意味着0x100~0x108会被加载到核心0和核心1的缓存中。现在当核心0修改0x100处的数据时,核心1中的缓存行就会失效。当核心1修改0x100处的数据时,它必须使用来自核心0缓存的数据更新其缓存行,并且核心0中的缓存行将失效。之后,它将写入0x100。如果这在循环中发生,大量带宽将浪费在缓存维护上。这是由于数据真实共享导致的缓存未命中,其中核心之间存在“真实共享”的数据字。
第二种类型是“数据错误共享”,即两个核心尝试访问并修改同一缓存行中的两个不同单元,导致另一个核心的缓存行不断失效。以前面的例子为例,假设核心0想要修改0x100,而核心2想要修改0x104。现在当核心0修改0x100处的数据时,将使核心1的缓存行无效。当核心1修改0x104处的数据时,它必须使用来自核心0缓存的数据更新其自己的缓存行,并使核心0的缓存行失效。然后它会写入0x104处。如果这样循环执行,也会导致性能损失。这里的性能损失是由于两个核心之间的“数据错误共享”造成的。
据我理解,真共享是指多个内核频繁写入相同的共享变量的问题,而误共享则是指多个内核写入位于同一缓存行上的不同变量的情况。
在这两种情况下,为了加载最新版本,缓存必须经常被无效化,但无法通过添加填充以确保两个变量位于不同的缓存行来解决真正的共享问题。
参考资料:
真正的共享是指核心访问多个附近内存地址,这些地址已经被加载到单个缓存行中。第一个访问之后的每次访问都可以从缓存中获益。