c++ - 原子更新结构的两个成员的最佳方法?

标签 c++ c++11 atomic

我有一个包含两个数据成员的结构:

struct A{
    short b;
    short c;
};

和一个包含许多这些结构对象的 vector :

std::vector<A> vec;

在运行时数据成员 A.bA.c来自结构对象被设置为零/一个值x .然而,bc必须同时修改 - 一个不能单独更新,没有另一个。我正计划使用原子 compare_exchange_weak()进行更新。

我不确定是否应该将每个结构表示为 std::atomic<A>在 vector 中,或者我是否应该在结构中放置一个 union ,将两个短裤组合成一个 uint32_t然后修改这个:

union A {
    struct {
         short b;
         short c;
    };

    uint32_t d;
};

最好的解决方案是什么?我应该存储一个 vector :

std::vector<uint32_t>

并且在访问每个元素时,将 reinterpret_cast 转换为 A,以获得 d

我希望锁定的干扰尽可能小。

不需要可移植性,这将适用于 Linux、64 位、x86、GCC 4.8+ 编译器

最佳答案

除非您的目标硬件支持双重比较和交换(可能不是这种情况),否则我认为您只有两个可移植的解决方案:

  1. 引入更高级别的锁(互斥锁或自旋锁,取决于您的偏好)并在 b 上进行所有操作和 c在获得的锁的范围内。互斥锁很重,但是 std::atomic_flag即使在高争用情况下也是无锁且非常轻量级的。

  2. 将两个成员合并为一个 std::atomic<int>并拆分int进入short通过位掩码。请注意,这需要 sizeof(int) >= 2 * sizeof(short) .如果需要强制执行,请使用固定大小的整数类型。

要确定哪个解决方案最快,当然是基准测试。

如果你知道 struct A 的数量您将在编译时需要,我建议将它们放入 std::array .如果你不这样做,std::vector只要这个数字在 vector 的整个生命周期中保持不变就可以了。否则,因为 std::atomic<T>既不可复制也不可移动,您必须为 struct A 编写自己的复制/移动构造函数.

关于c++ - 原子更新结构的两个成员的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27247973/

相关文章:

c++ - 函数静态变量析构函数和线程

c++ - 正确对齐内存中模板,参数顺序不变

c++ - 外部模板和不完整类型

c++ - C/C++ 中的结构赋值是原子的吗?

multithreading - 原子内存排序性能差异

c++ - 将空包写入avi文件ffmpeg

c++ - 系统错误 0x5 : CreateFileMapping()

c++ - googletest:如果测试失败则执行附加操作

c++ - 执行比较和交换指令时微处理器是否禁用中断?

c++ - 在比较 2 个短裤的过度对齐结构时,gcc 是否错过了优化机会?