我正在查看英特尔的“whatif”站点和他们的事务内存编译器(每个线程都必须进行原子提交或回滚系统内存,就像数据库一样)。
这似乎是替换锁和互斥锁的一种有前途的方法,但我找不到很多推荐。这里有人有意见吗?
我正在查看英特尔的“whatif”站点和他们的事务内存编译器(每个线程都必须进行原子提交或回滚系统内存,就像数据库一样)。
这似乎是替换锁和互斥锁的一种有前途的方法,但我找不到很多推荐。这里有人有意见吗?
我没有使用英特尔的编译器,但是,Herb Sutter 对此有一些有趣的评论......
您是否看到了对事务内存的大量兴趣和使用,或者这个概念对于大多数开发人员来说太难掌握了?
目前还无法回答谁在使用它,因为它还没有推向市场。英特尔有一个软件事务内存编译器原型。但如果问题是“开发人员使用起来是否太难了?” 答案是我当然希望不会。关键是它比锁更容易。这是研究范围内唯一希望大大减少我们对锁的使用的主要事物。它永远不会完全替换锁,但部分替换它们是我们唯一的大希望。
有一些限制。特别是,一些 I/O 本质上不是事务性的——你不能采用一个原子块来提示用户输入他的名字并从控制台读取名字,如果它与另一个事务冲突,就自动中止并重试该块;如果您提示他两次,用户可以分辨出区别。不过,事务性内存非常适合只接触内存的东西。
我认识的每个主要硬件和软件供应商都在研发中拥有多个事务性内存工具。有关于基本问题的理论答案的会议和学术论文。我们还没有到可以发货的 T 型阶段。您可能会看到早期的有限原型,在这些原型中您无法进行无限制的事务性内存——例如,您只能读取和写入 100 个内存位置。不过,这对于启用更多无锁算法仍然非常有用。
Dobb 博士去年有一篇关于这个概念的文章:Calum Grant 的 Transactional Programming -- http://www.ddj.com/cpp/202802978
它包括使用他的示例库的一些示例、比较和结论。
我在一些函数式编程思想的基础上构建了组合 STM 库。它不需要任何编译器支持(除了它使用 C++17),不会带来新的语法。一般采用Haskell的STM 库的接口。
所以,我的图书馆有几个不错的属性:
STML
。您可以将单子事务组合成更大的单子事务。TVars
并在其上运行事务。retry
组合器。它允许您重新运行事务。对于构建简短易懂的交易非常有用。Context
。每个计算都应该在某些上下文中运行,而不是在全局运行时中。因此,如果您需要多个独立的 STM 集群,您可以拥有许多不同的上下文。该库显示出非常好的稳定性和鲁棒性,即使我们认为它是实验性的。此外,我的方法为通过性能、功能、全面性等改进库提供了很多可能性。
为了展示它的工作,我已经解决了这个Dining Philosophers
任务。您可以在下面的链接中找到代码。示例交易:
STML<bool> takeFork(const TVar<Fork>& tFork)
{
STML<bool> alreadyTaken = withTVar(tFork, isForkTaken);
STML<Unit> takenByUs = modifyTVar(tFork, setForkTaken);
STML<bool> success = sequence(takenByUs, pure(true));
STML<bool> fail = pure(false);
STML<bool> result = ifThenElse(alreadyTaken, fail, success);
return result;
};
更新 我写了一个教程,你可以在这里找到它。
Sun Microsystems 宣布他们将在明年发布一款代号为 Rock 的新处理器,该处理器具有对事务内存的硬件支持。它会有一些限制,但这是一个很好的第一步,它应该使程序员更容易用事务替换锁/互斥锁,并期望从中获得良好的性能。
对于由 Sun 从事事务性记忆和摇滚研究的研究人员之一 Mark Moir 就该主题进行的有趣演讲,请查看此链接。
有关 Sun 关于 Rock 和 Transactional Memory 的更多信息和公告,请访问此链接。
强制性的维基百科条目:)
最后,威斯康星大学麦迪逊分校的这个链接包含关于事务性内存的大部分研究的参考书目,无论是硬件相关的还是软件相关的。
在某些情况下,我认为这是有用的,甚至是必要的。
但是,即使处理器具有使此过程更容易的特殊指令,与互斥锁或信号量相比,仍然存在较大的开销。根据它的实现方式,它也可能会影响实时性能(必须停止中断,或阻止它们写入您的共享区域)。
我的期望是,如果实现了这一点,那么只有给定内存空间的一部分才需要它,因此影响可能是有限的。
-亚当