Non*_*yme 8 c++ stdatomic c++20 stdmutex
我想知道如何才能std::atomic_ref有效地实现std::mutex非原子对象(每个对象一个),因为以下属性似乎很难实施:
相对于通过引用同一对象的任何其他atomic_ref施加的原子操作,通过atomic_ref施加到对象的原子操作是原子的。
特别是以下代码:
void set(std::vector<Big> &objs, size_t i, const Big &val) {
std::atomic_ref RefI{objs[i]};
RefI.store(val);
}
Run Code Online (Sandbox Code Playgroud)
似乎很难实现,因为std::atomic_ref每次都需要以某种方式进行选择std::mutex(除非这是由相同类型的所有对象共享的大主锁)。
我想念什么吗?还是每个对象都有责任实施std::atomic_ref,因此要么是原子的要么携带一个std::mutex?
实现与自身几乎完全相同std::atomic<T>。这不是一个新问题。
请参阅std :: atomic的锁在哪里? 一个典型的执行std::atomic/ std::atomic_ref锁的静态哈希表,通过地址索引,非无锁的对象。哈希冲突只会导致额外的竞争,而不会带来正确性问题。(死锁仍然是不可能的;锁仅由原子函数使用,从不尝试一次占用2个。)
例如,在GCC上,这 std::atomic_ref是调用__atomic_store对象的另一种方法。(请参阅GCC手册:atomic Builtins)
编译器知道是否T足够小以致可以无锁。如果不是,它将调用使用该锁的libatomic库函数。
(有趣的事实:这意味着它仅在对象具有足够的对齐方式时才起作用atomic<T>。但是在包括x86在内的许多32位平台上,uint64_t可能只有4字节对齐方式。 atomic_ref在这样的对象上可以编译并运行,但如果编译器使用32位SSE 8字节加载/存储来实现它。幸运的是alignof(T) == sizeof(T),像64位体系结构上的大多数原始类型那样,具有对象的对象没有危险。