使用当前的 C++ 编译器,您可以获得比 CPU 实际支持更大的原子支持。使用 x64,您可以拥有 16 字节的原子,但 std::atomic 也适用于更大的元组。看这段代码:
#include <iostream>
#include <atomic>
using namespace std;
struct S { size_t a, b, c; };
atomic<S> apss;
int main()
{
auto ref = apss.load( memory_order_relaxed );
apss.compare_exchange_weak( ref, { 123, 456, 789 } );
cout << sizeof ::apss << endl;
}
Run Code Online (Sandbox Code Playgroud)
对于我的平台,上面的 cout 总是打印 32。但是,如果没有互斥体,这些事务实际上是如何工作的呢?我从检查拆卸中没有得到任何线索。
如果我使用 MSVC++ 运行以下代码:
#include <atomic>
#include <thread>
#include <array>
using namespace std;
struct S { size_t a, b, c, d, e; };
atomic<S> apss;
int …Run Code Online (Sandbox Code Playgroud) 我在频繁使用的 if 上使用[[likely]]/ 。[[unlikely]]我最近有一个循环,其中条件很少满足,即循环很少进入或重复。
是否可以[[unlikely]]循环播放?在 en.cppreference.com 上我没有找到任何相关内容。
原子是否将可重复读取缓存在寄存器中?或者它们只是原子的,即读取可能不会分成多个部分?
MSVC++、clang++ / clang-cl 和 g++ 不会在没有内存排序的情况下缓存原子读取:
#include <atomic>
using namespace std;
int x( atomic_int const &ai )
{
int
a = ai.load( memory_order_relaxed ),
b = ai.load( memory_order_relaxed );
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
克++:
movl (%rdi), %edx
movl (%rdi), %eax
addl %edx, %eax
ret
Run Code Online (Sandbox Code Playgroud)
铿锵-cl:
mov eax, dword ptr [rcx]
add eax, dword ptr [rcx]
ret
Run Code Online (Sandbox Code Playgroud)
CL:
mov edx, DWORD PTR [rcx]
mov eax, DWORD PTR [rcx]
add eax, edx
ret 0`
Run Code Online (Sandbox Code Playgroud)