【发布时间】:2018-05-11 18:38:41
【问题描述】:
如果一个数据结构中有多个元素,它的原子版本不能(总是)是无锁的。 有人告诉我,这对于较大的类型是正确的,因为 CPU 不能在不使用某种锁的情况下自动更改数据。
例如:
#include <iostream>
#include <atomic>
struct foo {
double a;
double b;
};
std::atomic<foo> var;
int main()
{
std::cout << var.is_lock_free() << std::endl;
std::cout << sizeof(foo) << std::endl;
std::cout << sizeof(var) << std::endl;
}
输出(Linux/gcc)是:
0
16
16
由于 atomic 和 foo 的大小相同,我不认为在 atomic 中存储了锁。
我的问题是:
如果一个原子变量使用了锁,它存储在哪里,对于该变量的多个实例意味着什么?
【问题讨论】:
-
您是否尝试过使用大于 16 字节的类型?我对 x86 架构不是很熟悉,但如果它有一个 16 字节的 CAS 指令,就不需要显式锁定,我不会感到惊讶。
-
@Xirema 在这种情况下,我希望
is_lock_free()是true. -
@Xirema:x86-64 Linux 上的 gcc / clang 确实使用
lock cmpxchg16b(如果可用),但 gcc7 及更高版本仍然为is_lock_free返回 false,即使在技术上它是;但是纯负载和纯存储速度很慢,并且纯负载相互竞争。请参阅is_lock_free() returned false after upgrading to MacPorts gcc 7.3 以获取有关此设计决策的更多详细信息的链接。 -
@James 不,这违背了 std::atomic 的目的。
-
根据github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/…,clang(可能还有 gcc)使用原子的地址作为锁哈希图中的索引。
标签: c++ c++11 x86 atomic stdatomic