【问题标题】:How do I implement the ABA solution?如何实施 ABA 解决方案?
【发布时间】:2012-06-05 17:08:01
【问题描述】:

我正在尝试从here 实现 Michael-Scott FIFO 队列。我无法为 ABA 问题实施他们的解决方案。我收到此错误。

error: incompatible type for argument 1 of '__sync_val_compare_and_swap'

作为参考,我正在使用 linux 机器在英特尔架构上编译它。如果您需要有关我的设置的更多信息,请询问。

似乎sync_val_CAS 最多只能处理 32 位值。因此,当我删除他们用于消除 ABA 问题的计数器时,一切都编译并运行良好。

有人知道我应该在这里使用的相关 64 位 CAS 指令吗?

还有一个问题,是否有更好(更快)的无锁 fifo 队列实现?我遇到了 Nir ​​Shavit 等人的 this,这似乎很有趣。我想知道其他人是否看到过类似的努力?谢谢。

【问题讨论】:

  • 解决方案 ABA 产生解决方案 CDC 或解决方案 BEB
  • 您使用哪种语言? C?
  • 请参阅stackoverflow.com/questions/38984153/…,了解具有比较交换更新但仅有效加载指针(使用联合)的 C++11 指针 + ABA-counter 结构。

标签: linux concurrency intel fifo lock-free


【解决方案1】:

假设 gcc,尝试使用“march”开关。像这样:-march=i686

还有 __sync_bool_compare_and_swap。我不知道它是否更快。

【讨论】:

  • CMPXCHG16B 需要 -mcx16
  • 我们在 intel 上使用 redhat linux,march=i686 是适合我们的开关之一。我们只是选择了它,因为它就像一个主开关,也可以打开其他好东西。我记得我们让原子内置函数也可以与其他开关一起使用。
  • @Damon。嘿,这是一个 16 字节的 CAS 吗?喔喔喔喔喔。一个可以同时使用两个单独的 8 字节位置执行两个单独的 8 字节位置的方法会更好。所以我们可以更轻松地做更多事情。
  • 感谢 johnnycrash 提供的信息,它很有帮助,但并非完全如此。设置 -march=i686 给我错误“错误:您选择的 CPU 不支持 x86-64 指令集”。这似乎表明我的 CPU 没有 64 位指令,但事实并非如此。 'uname -a' 证实了这一点,因为它的输出中包含 x86_64。此页面有更多信息。 gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html。似乎表明 -march=native 可以解决问题,但也不会继续这样做。仅供参考,我正在使用英特尔至强 proc。我在这里错过了什么?
  • 试试我的确切设置:-march=i686 -pipe -m32。你是编译 64 位还是 32 位?我想我记得那里可能需要不同的开关的问题。它是什么氙气? en.wikipedia.org/wiki/Xeon。看起来并不是每个氙气灯都具有 64 位功能,但我真的不知道。我很确定 -march 开关或那个 gcc 页面上的开关是你想要的。和他们一起玩。
【解决方案2】:

GCC,我最后一次查看是在 2009 年,不支持连续双字 CAS。我必须实现内联汇编。

你可以在这里找到我对 M&S 队列的实现(包括抽象层中 DCAS 的组装实现)和其他无锁数据结构;

http://www.liblfds.org

简单地看一下 Nir ​​Shavit 等人的论文,队列需要安全内存回收,我怀疑你需要实现它 - 它不会内置到队列中。下一个版本(几周)将提供 SMR API。

【讨论】:

  • 感谢库。听起来会很有帮助。不幸的是,我无法使用它。它构建良好,在 /bin 目录中生成一个 liblfds.a 文件。然后,当我编译我的程序时,我只是简单地链接它,但链接器无法找到 queue_new。我收到此错误“未定义对 `queue_new(queue_state**, unsigned long long) 的引用”这可能是微不足道的,我觉得这是一个新手问这个问题,但也许你可以指出我做错了什么?我试过 'g++ myprog.cpp path/to/libflds.a' 以及 'g++ -L/path/to/libflds.a -llfds myprog.cpp'
  • 同样出于好奇,你有没有遇到过this 版本的 Michael Scott 队列?它看起来很有趣,虽然有点复杂。一旦我弄清楚了,我会尝试在 flds 中实现它,看看它是否能带来他们声称的性能优势。
  • 我想你可能正在经历名字修饰。 liblfds 是一个 C 库 - 我用 gcc 编译它。 g++ 可能试图链接到它,就好像它是一个 C++ 库一样。有一个关于名称装饰的谷歌。
  • 那个版本的 M&S 队列 M&S 队列 :-) 它在 liblfds 中实现。一旦你了解它,它就非常简单。
  • 不,我试过 gcc,同样的问题。 'gcc myprog.c path/to/libflds.a' 应该可以正常工作吗?
【解决方案3】:

无锁可能不是您想要的,因为无锁不一定是无等待的。如果您需要一个快速的线程安全队列(不是无锁的!),请考虑使用Threading Building Blocks concurrent_queue

【讨论】:

    猜你喜欢
    • 2015-04-01
    • 2020-10-03
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2022-01-24
    相关资源
    最近更新 更多