我正在开发我的无锁数据结构库的下一个版本,使用 ARM 上的 LL/SC。
对于 LL/SC 的用例,我需要将其与 LDREX 和 STREX 之间的单个 STR 一起使用。 (而不是用它来模拟 CAS。)
现在,我已经编写了代码并且可以运行。
然而,令我担心的是它可能并不总是有效。
我在 PowerPC 上读过,如果您访问与 LL/SC 目标相同的缓存行,就会破坏 LL/SC。
所以我在想,如果我的 STR 目标与我的 LL/SC 目标位于同一缓存行,那么 pow,我就死定了。
现在,LL/SC 目标和 STR 目标始终位于不同的 malloc() 中,因此它们直接位于同一缓存行中的机会可能很小(我可以通过填充 LL/SC 目标来保证这一点,因此它开始于缓存行边界并填充该缓存行)。
但如果 STR 目标位于内存中正确(错误!)的位置,则可能存在错误共享。
查看 LDREX/STREX 文档,这描述了“物理地址”方面的独占访问。这意味着寄存器宽度粒度,而不是高速缓存行宽度粒度。
这就是我的问题 - LDREX/STREX 对使用寄存器宽度粒度或缓存行宽度粒度的内存访问是否敏感?
ARM 使用独占监视器通过加载链接/条件存储来实现对内存的独占访问。 [1] 包含所有细节,我想说的重要的是:
独家预订颗粒
当独占监视器标记一个地址时,可以的最小区域
被标记为独占访问称为独占预订
颗粒(ERG)。 ERG 由实现定义,范围为 8-2048
字节,两个字节的倍数。可移植代码不得假设
有关 ERG 大小的任何信息。
所以在我看来你有点不走运。无论如何,大多数实际实现可能会保留一个较小的值,但据我所知,基本 ARM 架构并不能保证这一点,但也许有更多经验的人会发现我错了。 :)
尽管如此,LL/SC 的所有实现都是某种形式的弱 LL/SC,因此您几乎永远无法完全确定 LL 和 SC 之间的存储不会总是杀死 SC,或者大多数情况下时间,或者也许永远不会......它只是如此依赖于架构和实现,我个人坚持使用 LL/SC 在紧密循环中实现 CAS,并像往常一样使用它并完成它。
[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/CJAGCFAF.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)