gpt4 book ai didi

java - Java 中的 spin-on-test-and-set 与 spin-on-read

转载 作者:行者123 更新时间:2023-11-30 01:46:49 25 4
gpt4 key购买 nike

背景

我正在使用开源off-heap缓存实现,ohc

最近,我发现了一个pull request在 github 上建议

replace spin-on-compare-and-set with spin-on-read.

Here就是代码的改变,只增加了一行while(lockFieldUpdater.get(this) != 0L),就像

    while (true)
{
if (lockFieldUpdater.compareAndSet(this, 0L, t))
return true;

// while(lockFieldUpdater.get(this) != 0L)
Thread.yield();
}

基准性能

我编译它并使用 benchmark tool测试一下:

enter image description here

在线表现

然后我在生产中使用它,原来的平均读取时间成本约为 35,000 纳秒,而新版本只花费了 10,000 纳秒。

enter image description here

问题

这两种实现有什么区别?为什么在这种情况下读取测试要快得多?

最佳答案

为了理解性能提高的原因,最好了解一点缓存一致性协议(protocol)。原始版本仅依赖于严格的读取-修改-写入操作,并且如果失败则产生。这是很严厉的,因为 CAS 操作会生成相当多的缓存一致性流量,以获得缓存行的所有权,使其他核心上的副本无效等。随着线程数量的增加,这种简单的方法会导致大量的争用。

修改后的版本是对简单方法的改进,因为它更好地同步了线程的操作。通过确保每个线程都在自己的缓存副本上旋转,只有当本地副本失效(在另一个核心中修改)时,该线程才会再次被允许尝试 CAS。

这与为什么 TATAS locks 非常相似是对简单 TAS 锁的改进。

至于为什么您的本地基准测试显示约 6% 的加速,而您的生产服务器看到约 3.5 倍的加速,可能有几个原因可以解释。

  1. 您的生产服务器可以从本地变量上旋转获益匪浅,因为跨 NUMA 节点的内存访问会严重影响性能。
  2. 随着争用锁的线程数量的增加,TAS 锁和 TATAS 锁的性能都会下降。但 TATAS 锁的降级速度比 TAS 锁慢。此博客条目Test-and-set spinlocks有一个很好的图表说明了这一点。也许您的本地基准太小,看不到任何显着的改进?

关于java - Java 中的 spin-on-test-and-set 与 spin-on-read,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57643980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com