Java中的硬件事务性内存,或者为什么同步将再次变得很棒

总览

硬件事务内存有潜力允许多个线程同时以推测方式访问相同的数据结构,并使缓存一致性协议确定是否发生冲突。 HTM旨在为您提供细粒度锁定的可伸缩性,粗粒度锁定的简单性以及几乎没有锁定的性能。 如果JVM支持,则您的程序或库是使用过程粒度锁定编写的,这可能意味着您的应用程序只需很少的更改即可扩展到更多的内核。

虽然在C和C ++中添加对此的支持并非易事,但可以在不更改字节码的情况下添加对JVM生成的本机代码的支持。

简而言之,这可以允许许多线程以推测方式并发地为锁执行同步块,甚至并发写入,并且处理器可以确定这是否是问题,然后重复执行该块直到没有问题为止。

什么是硬件事务内存,它将花费多少?

硬件事务内存已经存在了一段时间,但是直到最近它才成为主流。 随着英特尔为其第四代i3 / i5 / i7处理器(Haswell)和其E3-1200 v3(最多4核,一个插槽ATM)系列处理器中的某些处理器提供支持,新的基于Intel的计算机可广泛使用。 可能是在今年下半年或明年,我们才能看到更多的核心,这意味着HTM将会真正发挥作用。 AFAIK和AMD计划很快添加此功能。

顺便说一句,Azul的Vega系统已经使用了这项技术已有近十年的时间,我希望Azul能够最好地首先在JVM中实现该技术。

您将购买(也许已经购买)的硬件将执行此操作。 许多新型号的笔记本电脑都具有Haswell处理器,因为它们显着改善了功耗。

如何运作?

Java中经常使用同步块,以防万一。 为了简化代码,这些锁通常比最佳锁要粗糙得多。例如,对于任何操作,Hashtable锁整个对象/映射,而具有精细锁定的ConcurrentHashMap锁。 编写细粒度锁定很难正确,因此更容易出错。 硬件事务存储的目标是支持过程粒度锁定,但要获得精细粒度锁定的好处。 这对于重新优化代码不可行的代码特别有用。

private final Map map = new HashMap<>(); 

public synchronized PooledObject acquireObject(String key) {
    PooledObjectobject = map.get(key);
    if (object == null)
        map.put(key, object = new PooledObject());
    return map;
}

您可能会想到这种情况

  • 只看地图
  • 更新地图,但是在不同的地方,例如不同的键。
  • 很少尝试一次在两个线程中更新同一密钥。

你想要的是

  • 线程之间的并发执行。
  • 与没有锁定的代码相比,开销很小。
  • CPU或JVM可以完成所有工作来优化此功能,即您不必更改代码。

如果没有HTM,则即使大多数情况是读取操作,同步块也需要获得锁并强制执行序列化访问。

使用HTM,字节码可以变成伪码,像这样

public PooledObject acquireObject(String key) {
    int code;
    do {
        xbegin();
        PooledObjectobject = map.get(key);
        if (object == null)
            map.put(key, object = new PooledObject());
        return map;
    } while((code = xend()) == RETRYABLE);
    if (code != DONE) {
        // take corrective action such as
        // obtain a normal lock and repeat
    }
}

XEND指令划定了检查缓存中的推测性读集和写集的终点,以查看其中是否有被其他CPU /线程修改过的任何被访问的缓存行。 如果不是,则所做的更改将被提交。 否则,将放弃所有更改,并且可以重复循环。

注意:回滚事务意味着撤消更改,甚至可能意味着回滚没有明显副作用的对象创建。 如果确实有副作用,则可以使用XABORT指令来触发事务中止,并且需要运行后备代码。

比较和交换限制为64位,这些事务的限制是多少?

限制是您可以在L1缓存中存储的行数。 最多32 KB。 如果您有超线程,则可能只有一半,即16 KB。 同样,L1缓存是8路关联的,因此在最坏的情况下,哈希到同一存储桶的9条缓存行可能导致事务失败。 (具有超线程的情况较少),尽管如此,它比CAS 64位或128位的2CAS高得多,并且灵活得多。

使用后退编写此事务锁定结构,以使用C之类的语言添加样板和重复代码。

结论

这种模式的优点在于它可以应用于已经编译过的Java代码,并且可以作为开源库使用。 与需要大量返工才能利用此功能的C代码不同,Java程序无需重新编译即可利用HTM。 我们需要的是更改JVM。

注释(对我之前所说的内容进行了一些更正/澄清)

为了我; 我相信“酷”技术会引起广泛的兴趣,即使没有证明广泛的实用性。 我相信在主流JVM中实现此功能将挑战甚至是经验丰富的开发人员“了解”多线程编程的知识。

虽然某些Haswell处理器中提供了Intel TSX,但并非所有Haswell处理器中都提供了Intel TSX。 您应该在ARK上Haswell进行联系,并查看Intel TSX-NI是Yes

已经注意到,这对于调优的代码可能没有太大的区别。 英特尔TSX的设计师Ravi Rajwar在QCon SF 2012上的主题机械同情”的主题 是“英特尔的下一代微体系结构代号Haswell ”。 如果您看一下第29页,它向我建议,细粒度的代码无论如何都将在内核之间很好地扩展,并且不会获得太多收益。 TSX可能会帮助您的是粗粒度锁定。

有关更多技术细节,我建议您阅读Gil Tene在机械同情小组上的帖子 。 与我见过的任何人相比,他在调优JVM以支持HTM方面都有第一手的经验。

参考文献

参考: Java中的硬件事务存储,或者为什么同步将变得凉爽 ,我们的JCG合作伙伴 Peter Lawrey在Vanilla Java博客上发表了文章。

翻译自: https://www.javacodegeeks.com/2014/02/hardware-transactional-memory-in-java-or-why-synchronized-will-be-cool-again.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值