我正在查看英特尔的“whatif”网站及其事务内存编译器(每个线程必须进行原子提交或回滚系统内存,就像数据库一样)。

这似乎是一种替代锁和互斥体的有前途的方法,但我找不到很多推荐。这里有人有任何意见吗?

有帮助吗?

解决方案

我没有使用过英特尔的编译器,但是,Herb Sutter 对此有一些有趣的评论......

萨特讲话:并发的未来

您是否发现人们对事务内存有很多兴趣并使用它,或者这个概念对于大多数开发人员来说太难掌握?

目前还无法回答谁在使用它,因为它尚未推向市场。英特尔有一个软件事务内存编译器原型。但是,如果问题是“开发人员太难使用吗?”答案是我当然希望不要。重点是它比锁容易得多。这是研究领域中唯一有望大大减少锁的使用的重大事情。它永远不会完全取代锁,但部分取代锁是我们唯一的希望。

有一些限制。特别是,某些 I/O 本质上不是事务性的 - 您不能采用一个原子块来提示用户输入其姓名并从控制台读取该名称,并且如果它与另一个事务冲突,则自动中止并重试该块;如果您提示两次,用户就能分辨出差异。不过,事务性内存对于只涉及内存的东西来说非常有用。

据我所知,每个主要的硬件和软件供应商都在研发中拥有多种事务内存工具。有关于基本问题的理论答案的会议和学术论文。我们还没有达到可以发货的 T 型车阶段。您可能会看到早期的有限原型,您无法执行无限制的事务内存,例如只能读写 100 个内存位置。不过,这对于启用更多无锁算法仍然非常有用。

其他提示

博士。Dobb's 去年有一篇关于这个概念的文章:Calum Grant 的事务性编程—— http://www.ddj.com/cpp/202802978

它包括使用他的示例库的一些示例、比较和结论。

我基于一些函数式编程思想构建了组合 STM 库。它不需要任何编译器支持(除了它使用 C++17),也不会带来新的语法。一般来说,它采用的接口 STM库 来自哈斯克尔。

所以,我的库有几个不错的属性:

  • 单子组合。每个事务都是名为的自定义 monad 内的计算 STML. 。您可以将单子交易组合成更大的单子交易。
  • 事务与数据模型分离。您可以使用事务变量构建并发数据模型(TVars)并在其上运行事务。
  • retry 组合器。它允许您重新运行事务。对于构建简短且易于理解的交易非常有用。
  • 有不同的一元组合器可以快速表达计算。
  • Context. 。每个计算都应该在某个上下文中运行,而不是在全局运行时中运行。因此,如果您需要多个独立的 STM 集群,则可以拥有许多不同的上下文。
  • 从概念上讲,实现非常简单。至少, 参考实现 Haskell 中就是如此,但由于缺乏对函数式编程的良好支持,我不得不重新发明几种 C++ 实现方法。

即使我们认为它是实验性的,该库也显示出非常好的稳定性和鲁棒性。此外,我的方法为通过性能、功能、综合性等改进库提供了很多可能性。

为了演示它的工作,我解决了 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 公司研究事务内存和 Rock 的研究人员之一 Mark Moir 发表,请查看此内容 关联.

有关 Sun 关于 Rock 和事务内存的更多信息和公告,请访问 关联.

强制性的 维基百科条目 :)

最后, 这个链接, 威斯康星大学麦迪逊分校的 ,包含大部分已经和正在进行的有关事务内存的研究的参考书目,无论是与硬件相关的还是与软件相关的。

在某些情况下,我认为这是有用的,甚至是必要的。

然而,即使处理器具有使该过程更容易的特殊指令,与互斥体或信号量相比,仍然存在很大的开销。根据其实现方式,它也可能会影响实时性能(必须停止中断,或阻止它们写入您的共享区域)。

我的期望是,如果实现了这一点,那么只需要给定内存空间的一部分,因此影响可能是有限的。

-亚当

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top