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方面具有第一手经验。
参考资料
- 投机锁定:打破规模障碍(JAOO 2005),由阿祖尔( Azul)的吉尔·特内(Gil Tene)撰写。
- Sun Microsystems的David Dice,Yossi Lev,Mark Moir,Daniel Nussbaum,Marek Olszewski 的商业硬件事务存储实现的早期经验(2009年10月) 。
- Wikipedia上的事务同步扩展
- 基准:SiSoftware的Haswell的TSX和内存事务处理吞吐量(HLE和RTM)
- 享受来自英特尔的英特尔®事务同步扩展的乐趣
- 事务性内存支持:英特尔的speculative_spin_mutex
- Johan De Gelas讲解了Intel Haswell事务同步扩展 。
翻译自: https://www.javacodegeeks.com/2014/02/hardware-transactional-memory-in-java-or-why-synchronized-will-be-cool-again.html
java 内存同步