【问题标题】:lock free programming - c++ atomic无锁编程 - c++ atomic
【发布时间】:2013-12-11 15:56:53
【问题描述】:

我正在尝试开发以下无锁代码(c++11):

int val_max;
std::array<std::atomic<int>, 255> vector;

    if (vector[i] > val_max) {
    val_max =vector[i];
    }

问题是当线程很多时(128个线程),结果不正确,因为例如val_max=1,三个线程(vector[i] = 5, 15 and 20)会执行下一行的代码,这将是一场数据竞赛..

所以,我不知道用 c++11 中的可用函数(我不能使用互斥锁、锁)来保护整个代码的问题的最佳解决方法。

有什么建议吗?提前致谢!

【问题讨论】:

  • 描述你想要达到的目标。
  • 也许这会解决你的问题stackoverflow.com/questions/16190078/…
  • 更大的问题是,即使您摆脱了数据竞争,val_max 上的争用也会成为瓶颈,并扼杀您可能从多线程解决方案中获得的所有性能提升。你的算法似乎有缺陷,但由于你没有写出你想要实现的东西,所以很难帮助你修复它。

标签: c++11 atomic lock-free


【解决方案1】:

你需要描述你需要解决的更大的问题,以及为什么你需要多个线程来解决这个问题。

如果您有大量数据并且想要找到最大值,并且想要拆分该问题,那么您做错了。如果所有线程都试图访问一个共享的最大值,不仅很难做到正确,而且当你做对时,你已经完全序列化了访问,从而使整个事情成为增加复杂性和线程开销的练习。程序。

使其并行的正确方法是给每个线程一个数组块来处理(数组成员不是原子的),线程计算一个局部最大值,然后当所有线程完成后有一个线程找到单个结果的最大值。

【讨论】:

  • 正如我之前写的,这只是一个要求(线程数和无锁)。正如你所说,我给每个线程一个数组的一部分,但问题是,当有 128 个线程执行时,它们有时会执行同一行,而我的值是错误的......
  • 他们的关键是给他们局部最大值,最后聚合。如果你不能有一个单独的线程来总结这个,你需要使最终的 max_val 原子并使用 compare_exchange 循环来设置它。
【解决方案2】:
  1. val_max 进行原子提取。
  2. 如果获取的值大于或等于vector[i],停止,你就完成了。
  3. 进行原子比较交换 - 将 val_max 与您在第 1 步中读取的值进行比较,如果比较,则将其交换为 vector[i] 的值。
  4. 如果比较成功,停止,你就完成了。
  5. 转到第 1 步,您与另一个取得进展的线程竞争。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多