2012-03-04 182 views
10

我想使用std :: atomic庫。C++,C++ 11,std ::原子成員函數

  1. 什麼之間的差別專業非專業原子 成員函數?
  2. 下列功能之間有什麼區別(如果有的話)?
  3. 運算符=存儲值到原子對象(公共成員函數)V.S. 商店(C++ 11)原子替換爲一個非原子參數的原子對象的值(公共成員函數)
  4. 算子T()負載從一個原子對象的值(公共成員函數)V.S. 加載(C++ 11)自動獲取原子對象(公共成員函數)的值。
  5. 操作者+ = V.S. fetch_add
  6. operator- = v.s. fetch_sub
  7. 運營商& = v.s. fetch_and
  8. 運營商| = v.s. fetch_or
  9. operator^= v.s. fetch_xor
  10. 什麼是一個變量聲明爲原子V.S.的缺點一個 非原子變量。例如, std::atomic<int> x v.s.有什麼缺點? int x?換句話說,一個原子變量的開銷是多少?
  11. 哪一個有更多的開銷?一個原子變量v.s.一個正常的 變量受互斥鎖保護?

下面是引用我quesitons。 http://en.cppreference.com/w/cpp/atomic/atomic

+0

我認爲這將是值得你花時間研究一個特定的架構原子CPU指令和內存屏障,以更好地瞭解如何實現原子操作的內部。請參閱此處以獲取x86上的起點:http://www.mohawksoft.org/?q=node/78,並查找英特爾手冊作爲參考:http://www.intel.com/content/www/us /en/processors/architectures-software-developer-manuals.html – 2012-11-05 11:44:15

回答

10

不是專家,但我會嘗試:

  1. 的特化(對於內置類型,如int)包含額外的操作,例如fetch_add。非專用表單(用戶定義的類型)將不包含這些。
  2. operator=返回它的參數,store沒有。另外,非運算符允許您指定一個內存順序。該標準說operator=是根據store定義的。
  3. 與上面相同,但它返回的load值。
  4. 同上
  5. 同上
  6. 同上
  7. 同上
  8. 同上
  9. 同上
  10. 他們做不同的事情。在您使用std::atomic_int的方式中使用int的行爲是未定義的。
  11. 你可以假定開銷int <= std::atomic <= int and std::mutex其中<=意味着「更少的開銷」。所以它可能比鎖定互斥鎖更好(特別是對於內置類型),但比int更糟糕。
+0

謝謝你的回覆,你能解釋一下什麼是memory_order?我在這裏找到了參考和幾個例子,http://en.cppreference.com/w/cpp/atomic/memory_order。但是不太明白。 謝謝。 – 2607 2012-03-04 08:57:17

+1

@ 2607「memory_order」很難解釋和理解。首先,你必須知道的一點是你總是應該使用'seq_cst',這是默認的默認值。第二個近似,可以將每個'原子'訪問看作由訪問之前獲取的互斥體所保護,並在之後發佈。與任何關鍵部分一樣,其他程序操作可以轉移到關鍵部分,但不能脫離。 「獲取」語義允許其他操作向下移動但不起來; 「釋放」語義允許向上但不向下。第三個近似值,我不知道。 – Quuxplusone 2012-10-19 18:47:01

+0

std :: atomic被設計成在情況許可的情況下(例如,在x86上具有寬鬆內存順序的情況下)與簡單整數相比是無開銷的。在這種情況下的另一個重要信息是std :: atomic可以在本機不支持這些操作的平臺上以互鎖方式實現算術運算。因此,一般來說,如果有足夠的爭論,這篇文章中的第二個不平等運營商可能(或不可能)轉向。 – Dude 2012-10-20 13:35:54

0

我不是這個東西的專家,但如果我在你的參考正確理解非專業操作原子地做一兩件事,加載,存儲,更換等

的專業功能做兩事物是原子性的,也就是說他們修改並返回一個原子對象,使得這兩個操作在任何其他線程可能混淆它們之前發生。

9

什麼專業和非專業的原子成員函數之間的區別?

如可以在這些類的在標準的synposis可以看出(§29.5),有三種不同的組成員函數:

  • 最通用的一個只提供存儲,負載,交流和比較交換操作;
  • 除了通用類型之外,整數類型的專門化還提供原子算術和位運算;
  • 除了通用指針之外,指針專用還提供指針算術運算。

以下函數之間有什麼區別(如果有的話)?

operator=將值存儲到原子對象(公共成員函數)v.s.中。 store(C++ 11)原子替換爲一個非原子參數的原子對象的值(公共成員函數)

(...)

主要的功能不同的是,非運算符版本(第29.6.5節,第9-17段和更多)具有用於指定所需內存排序(第29.3/1)的額外參數。運營商版本使用順序一致性內存排序:

void A::store(C desired, memory_order order = memory_order_seq_cst) volatile noexcept; 
void A::store(C desired, memory_order order = memory_order_seq_cst) noexcept; 

要求:順序參數不應memory_order_consumememory_order_acquire,也不memory_order_acq_rel

影響:原子上用對象或由此指向的值替換所需的值。根據order的值 ,內存受到影響。

C A::operator=(C desired) volatile noexcept; 
C A::operator=(C desired) noexcept; 

效果:store(desired)

返回:desired

非操作形式是有利的,因爲順序一致性並不總是必需的,並且它可能比更昂貴的其他記憶順序。通過仔細分析,您可以找出正確操作所需的最低限度保證,並選擇限制性較低的內存排序之一,爲優化程序提供更多回旋餘地。

將變量聲明爲原子v.s.的缺點是什麼?一個非原子變量。例如,std::atomic<int> x v.s.有什麼缺點? int x?換句話說,一個原子變量的開銷是多少?

當常規變量足以限制可能的優化次數時使用原子變量,因爲原子變量強加了不可分割性和(可能)內存排序的附加約束。

使用時需要一個原子變量可以引入數據爭經常可變的,這使得未定義的行爲(§1.10/ 21):

一個程序的執行包含數據爭如果它在不同的線程中包含兩個衝突的動作,其中至少有一個不是原子的,並且兩個線程都不會發生在另一個線程之前。任何這樣的數據競爭都會導致未定義的行爲。

原子變量的開銷是實現質量的問題。理想情況下,當您需要原子操作時,原子變量的開銷爲零。當你不需要原子操作時,它可能會有的開銷是無關緊要的:你只需要使用一個常規變量。

哪一個有更多的開銷?一個原子變量v.s.一個由互斥鎖保護的正常變量?

沒有理由爲一個原子變量具有比互斥保護正常的變量更多的開銷:最壞的情況下,原子變量實現就這樣。但是有可能原子變量是無鎖的,這會涉及更少的開銷。該屬性可以在標準§29.6.5/ 7所描述的功能來確定:

bool atomic_is_lock_free(const volatile A *object) noexcept; 
bool atomic_is_lock_free(const A *object) noexcept; 
bool A::is_lock_free() const volatile noexcept; 
bool A::is_lock_free() const noexcept; 

返回:真如果對象的操作是無鎖的,否則爲false。