我有一个包含两个数据成员的结构:
struct A{
short b;
short c;
};
和一个包含许多这些结构对象的 vector :
std::vector<A> vec;
在运行时数据成员 A.b
和 A.c
来自结构对象被设置为零/一个值x
.然而,b
和 c
必须同时修改 - 一个不能单独更新,没有另一个。我正计划使用原子 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+ 编译器
最佳答案
除非您的目标硬件支持双重比较和交换(可能不是这种情况),否则我认为您只有两个可移植的解决方案:
引入更高级别的锁(互斥锁或自旋锁,取决于您的偏好)并在
b
上进行所有操作和c
在获得的锁的范围内。互斥锁很重,但是std::atomic_flag
即使在高争用情况下也是无锁且非常轻量级的。将两个成员合并为一个
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/