先看一段**
#include
#include
int a =0;
int b =0;
void
func1()
void
func2()
intmain
(void
)
再看一段彙編**:
1: load reg3, 1 ;將立即數1放入暫存器reg3
2: move reg4,reg3 ;將reg3的資料放入reg4
3: store reg4, a ;將reg4的資料存入記憶體位址a
4: load reg5, 2 ;將立即數2放入暫存器reg5
5: store reg5, b ;將reg5的資料存入記憶體位址b
以上的偽彙編**代表了temp = 1; a = temp; b = 2;
通常情況下指令都是按照1~5的順序執行,這種記憶體模型稱為強順序(strong ordered)。
不過可以看到,指令1、2、3和指令4、5的執行順序不影響結果。
有一些處理器可能會將指令的順序打亂,例如按照1-4-2-5-3的順序執行,這種記憶體模型稱為弱順序(weak ordered).
如果乙個平台是弱順序記憶體模型,那麼上文列印a,b的**中,執行緒func2就有可能列印出0,2的結果。
既然弱順序記憶體模型可能會導致程式問題,為什麼有些平台會使用這種模型?
簡單的說,這種模型能讓處理器有更好的並行性,提高指令執行的效率。
為了保證指令的順序執行,需要在彙編指令中加入一條記憶體柵欄指令(memory barrier)。
它能保證指令的順序執行,但是會影響處理器效能。
c++11中的原子操作還可以包含乙個引數:記憶體順序(memory_order)
memory_order 是c++11為原子型別定義的記憶體模型,以便靈活地控制原子型別的執行順序。
**通常情況下,使用該引數將有利於編譯器進一步提高並行效能。**如下:
atomic<
int>a(
0);atomic<
int>b(
0);void
func1()
上面的**使用了store
函式進行賦值。store函式有2個引數,第乙個是要寫入的值,第二個是名為memory_order
的列舉值。
這裡使用了std::memory_order_relaxed
,表示鬆散記憶體順序,該列舉值代表可以任由編譯器重新排序或則由處理器亂序處理
。
這樣a和b的賦值執行順序性就被解除了。
在c++11中一共有 6種 memory_order列舉值,預設按照memory_order_seq_cst
執行:
列舉值含義
memory_order_relaxed
不對執行順序做任何保障
memory_order_acquire
本執行緒中,所有後續的讀操作均在本條原子操作完成後執行
memory_order_release
本執行緒中,所有之前的寫操作完成後才能執行本條原子操作
memory_order_acq_rel
同時包含memory_order_acquire和memory_order_release標記
memory_order_consume
本執行緒中,所有後續的有關本原子型別的操作,必須在本條原子操作完成後執行
memory_order_seq_cst
全部訪問都按順序執行
注意: 不是所有的memory_order都能被atomic成員使用:
原子型別提供的一些操作符,比如operator=
、operator+=
等函式,都是以memory_order_seq_cst為實參的原子操作封裝,所以他們都是順序一致性的。
如果要指定記憶體順序的話,則應該採用store
、load
、atomic_fetch_add
這樣的函式。
最後說明一下,std::atomic和std::memory_order只有在多執行緒無鎖程式設計時才會用到。在x86_64平台,由於是強順序記憶體模型的,為了保險起見,不要使用std::memory_order,使用std::atmoic預設形式即可,因為std::atmoic預設是強順序記憶體模型。
C 11記憶體模型
一 幾種同步關係 1.執行緒內部的資料關係 1.1 sequenced before 這是表示式與表示式之間的一種配對的不對稱的關係,僅用於同乙個執行緒內。實際執行順序不能破壞語句間sequenced before的關係。1 的1.9.13 1.2 carries a dependency to 僅...
c 11 記憶體模型解讀
說到記憶體模型,首先需要明確乙個普遍存在,但卻未必人人都注意到的事實 程式通常並不是總按著照原始碼中的順序一一執行,此謂之亂序,亂序產生的原因可能有好幾種 編譯器出於優化的目的,在編譯階段將原始碼的順序進行交換。程式執行期間,指令流水被 cpu 亂序執行。inherent cache 的分層及重新整...
C 11 多工記憶體模型
記憶體模型 一般來說,記憶體模型可以分為靜態記憶體模型和動態記憶體模型 c 11的記憶體模型 std memory order就是c 11的記憶體模型。c 11為std atomic提供的memory order enum class memory order 雖然列舉定義了6個,但它們表示的是4種...