Chase-lev deque中的原子存储

问题描述 投票:3回答:1

我正在基于以下论文实现Chase-lev双端队列:“针对弱内存模型的正确有效的工作窃取”。在本文中,它要求双端队列必须具有包含原子元素的缓冲区:

struct Deque {
  std::atomic<size_t> size;
  std::atomic<int> buffer[];
}

为什么缓冲区中的元素类型为std::atomic<int>而不是普通的int

c++ atomic deque work-stealing
1个回答
0
投票

嗯,因为缓冲区元素是由不同的线程读取/写入的,并且您在写入与后续读取之间并不总是具有事前-事前关系。因此,如果缓冲区元素不是原子元素,则将导致数据争用。

如果您有兴趣,可以看一下我对chase-lev-deque的实现:https://github.com/mpoeter/xenium/blob/master/xenium/chase_work_stealing_deque.hpp

更新

问题是索引可以环绕。假设在调用topbottom之后但在可以从缓冲区读取该项目之前,调用secret的线程可能会被挂起。如果在此期间索引回绕,则该项目可能会被某些推送操作覆盖。因此,窃取中的装入操作将与该存储区没有先发生的关系。

该标准定义了如下的数据竞争:

如果程序的执行在不同线程中包含两个冲突的动作,其中至少一个不是原子的,并且在另一个之前都没有发生,则该执行将包含数据争用。

由于所描述的示例未提供对缓冲区的读写操作之间的先于关系,因此如果缓冲区不是原子的,这将是一场数据竞争。但是,原子永远不会参与数据争用,因此通过使缓冲区原子成为原子,我们可以完全防止由于不同步访问而导致的任何数据争用(即使这种操作被放松了)。

注意,这仅是为了防止对缓冲区的操作进行data races。推和窃操作之间的实际同步是通过底部的操作进行的。

© www.soinside.com 2019 - 2024. All rights reserved.