AFAIK C++原子公司(<atomic>
)家族提供3個好處:C++原子學和跨線程能見度
- 基本指令不可分割(無髒讀),
- 存儲器排序(既,對於CPU和編譯器)和
- 跨線程可見性/變化傳播。
我不確定第三個項目符號,因此請看下面的示例。
#include <atomic>
std::atomic_bool a_flag = ATOMIC_VAR_INIT(false);
struct Data {
int x;
long long y;
char const* z;
} data;
void thread0()
{
// due to "release" the data will be written to memory
// exactly in the following order: x -> y -> z
data.x = 1;
data.y = 100;
data.z = "foo";
// there can be an arbitrary delay between the write
// to any of the members and it's visibility in other
// threads (which don't synchronize explicitly)
// atomic_bool guarantees that the write to the "a_flag"
// will be clean, thus no other thread will ever read some
// strange mixture of 4bit + 4bits
a_flag.store(true, std::memory_order_release);
}
void thread1()
{
while (a_flag.load(std::memory_order_acquire) == false) {};
// "acquire" on a "released" atomic guarantees that all the writes from
// thread0 (thus data members modification) will be visible here
}
void thread2()
{
while (data.y != 100) {};
// not "acquiring" the "a_flag" doesn't guarantee that will see all the
// memory writes, but when I see the z == 100 I know I can assume that
// prior writes have been done due to "release ordering" => assert(x == 1)
}
int main()
{
thread0(); // concurrently
thread1(); // concurrently
thread2(); // concurrently
// join
return 0;
}
首先,請驗證我在代碼中的假設(特別是thread2
)。
其次,我的問題是:
怎樣的
a_flag
寫傳播到其他核心?std::atomic
是否將寫入器緩存中的a_flag
與其他內核緩存(使用MESI或其他)進行同步,或者傳播是自動的?假設在一臺特定的機器上寫入一個標誌是原子的(在x86上認爲是int_32)並且我們沒有任何私有內存來同步(我們只有一個標誌)我們是否需要使用原子?
考慮到最流行的CPU體系結構(86,64,ARM v.whatever,IA-64),是跨芯能見度(我現在不考慮重排序)自動的(但可能延遲),或者你需要發佈特定的命令來傳播任何數據?