31

是否有任何小型库,将各种处理器的类似 CAS 的操作包装成宏或函数,可以跨多个编译器移植?

PS。atomic.hpp位于 boost::interprocess::detail 命名空间内。作者拒绝让它成为一个公共的、维护良好的图书馆。

让我们重新打开这个问题,看看是否还有其他选择?

4

9 回答 9

30

OPA(开放便携式原子)可能非常适合您的需求。 https://trac.mcs.anl.gov/projects/openpa/

它在 MIT 风格的许可下为跨多个平台的常见原子操作提供一致的 C API。图书馆很小,当然可以满足您的大小要求。当前平台列表为:

  • 适用于 x86、x86_64、ia64、PPC 440 和 MIPS 5K 处理器的 GCC 内联汇编。在相同的架构上也支持多个具有 GCC 兼容的前端的编译器,例如 icc、PGI 和 IBM 的 xlc。
  • GCC 原子内在函数,因此支持大多数 GCC-4.1+ 安装。
  • SUN Solaris 原子操作库。
  • Windows NT 内在函数(尽管您目前必须做一些额外的工作才能在 Windows 上构建)。
  • 两个伪平台,基于 pthread mutex 的仿真,用于移植到其他不受支持的平台(同时牺牲一些性能),以及用于有条件编译为单线程代码的代码的“不安全”实现。

我从来没有在 C++ 程序中使用过它,尽管它应该可以在很少或没有变化的情况下工作。如果您遇到麻烦,我很乐意对其进行调整(只需发送邮件 opa-discuss@lists.mcs.anl.gov)。

于 2009-08-20T14:16:07.507 回答
25

boost 进程间库可能是您所追求的——Atomic.hpp 包含文件包含适用于各种平台和编译器的比较和交换实现。

于 2009-07-21T10:39:36.510 回答
15

Intel Threading Building Blocks有一个很好的可移植atomic<T>模板,可以满足您的需求。但是否是小型图书馆当然可以争论。

于 2009-07-28T13:15:00.573 回答
11

你可能对Glib 的原子操作函数感兴趣,

g_atomic_int_compare_and_exchange()

为各种架构实现 CAS 语义。实现本身比较容易理解,可以独立使用,不需要太多努力,你可以在 svn.gnome.org/viewvc/ 下的 glib/trunk/glib/gatomic.{c,h} 下找到它。希望这可以帮助!

于 2009-07-24T22:34:11.250 回答
9

在 Mac OS X 和 Windows 上,无论如何都应该使用内置的 CompareAndSwap 函数(分别为 InterlockedCompareExchange() 和 OSAtomicCompareAndSwapPtrBarrier())。因此,无论这些平台上的编译器如何,都可以工作。

在其他 Unix 上,这有点棘手,如果您使用的是 GCC 4.1 或更高版本,您可以只使用其内置的 __sync_val_compare_and_swap(),尽管并非所有的 unix 编译器都支持合理的 gcc 扩展,因为许多源自 Linux 的代码假定它们存在.

因此,如果您想以一种适用于 OS X 和 Windows 上所有处理器的大多数编译器以及其他平台上的 GCC 和其他一些编译器的方式将它们包装起来,您应该执行以下操作:

boolean CompareAndSwapPointer(volatile * void * ptr,
                                  void * new_value,
                                  void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
  return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
#  error No implementation
#endif
}

那没有经过测试,但我认为它应该是正确的。请注意所有操作系统库如何以不同的顺序获取参数 ;-)

显然,您可以为不同大小的比较和交换做几个版本,如果需要,可以将它们包装在模板中。API 大多是基于 C 的,并将类型信息编码到函数中,这对于习惯于通过模板参数化类型的人来说有点讨厌。

于 2009-07-27T17:54:33.190 回答
6

Boehm 有atomic_ops项目的库。不过,不知道许可证。

于 2009-07-28T20:52:46.857 回答
3

有一个提议的 C++0x 兼容的 Boost atomics 库: http: //www.chaoticmind.net/~hcb/projects/boost.atomic/

这个库的目的是为 boost 提供原子操作的实现,基于 C++0x 草案标准指定的接口。它旨在使转换到 std::atomic 变得容易,并提供一种使使用此 C++0x 功能的代码可在旧系统上编译的方法。

它显然还不是 Boost 的一部分,但你可以在这里查看评论线程:http: //lists.boost.org/Archives/boost/2009/12/160195.php

Boost.Atomic 现在是一种我认为称之为发布的形式。它支持“真正的”原子变量:

  • gcc/x86,32 位(在 Linux、FreeBSD 上测试)
  • gcc/x86,64 位(在 Linux 上测试)
  • gcc/powerpc32(在 Linux、Mac OS X 上测试)
  • gcc/powerpc64(未经测试)
  • 通用 Win32(在 Win XP 上使用 Visual Studio Express 测试)

对于所有其他人,它会优雅地退回到锁定操作。有适当的快速手册文档,包括一个有希望的说明性示例部分。

于 2010-08-16T19:19:31.167 回答
2

作者所说的(在您提供的链接中)是“我认为您可以安全地使用它们,直到一些官方 Boost 库出现”。将接口更改推迟到“当原子函数将出现在 C++0x 中时”。

无论您今天使用什么,您都可能希望在新std::功能可用时迁移到它。

Boost 的东西通常都很好,看起来它被用于实现已发布的 Boost 库。我也曾多次尝试使用该实现。

我会去的。

于 2009-07-28T21:10:46.290 回答
0

您还可以从http://www.ioremap.net/node/224查看 libsync 的灵感,这是相当新的(可能太新了),但它正在 Elliptics Network 中使用,所以它确实得到了(一些?)测试。

它还为您提供了 CAS 旁边的更高级别的原语:RCU(读取复制更新),用于线程之间的无锁同步。

但这取决于您所说的“便携式”是什么意思:它支持架构 x86 和 PPC、操作系统 Linux、FreeBSD、OpenBSD、Solaris 和 MacOSX,但……不支持 Windows。

许可证是 GPL,你可以讨厌或喜欢它。

于 2009-07-29T20:28:11.873 回答