日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Memory Ordering

發布時間:2024/9/5 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Memory Ordering 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Background
很久很久很久以前,CPU忠厚老實,一條一條指令的執行我們給它的程序,規規矩矩的進行計算和內存的存取。
很久很久以前, CPU學會了Out-Of-Order,CPU有了Cache,但一切都工作的很好,就像很久很久很久以前一樣,而且工作效率得到了很大的提高。
很久以前,我們需要多個CPU一起工作,于是出現了傳說中的SMP系統,每個CPU都有獨立的Cache,都會亂序執行,會打亂內存存取順序,于是事情變得復雜了…… Problem
由于每個CPU都有自己的Cache,內存讀寫不再一定需要真的作內存訪問,而是直接從Cache里面操作,同時CPU可能會在合適的時候對于內存訪問進行重新排序以提高效率,在只有一個CPU的時候,這很完美。
而當有多個CPU的時候——
  • 從Cache到內存的flush操作通常是被延遲的,所以就需要某種方法保證CPU A進行的內存寫操作真的可以被CPU B讀取到。
  • CPU可能會因為某些原因(比如某兩個變量同在一個Cacheline中)而打亂
    • 實際內存寫入順序
    • 實際內存讀取順序
    所以就需要某種方法保證在需要的時候
    • 之前的讀寫操作已經完成
    • 未來的讀寫操作還沒開始
考慮一個例子:
Thread A:
while (flag == 0)
??????? ; // do nothing
printf("%d\n", data);
Thread B:
data = 523;
flag = 1;
這里data代表了某種數據,它可以像這里一樣是一個簡單的整數,也可能是某種復雜的數據結構,總之,我們在Thread B中對data進行了寫入,并利用flag變量表示data已經準備好了。
在Thread A中,一個忙等待直到發現data已經準備好了,然后開始使用data,這里是簡單的把data打印出來。
現在考慮如果CPU發現對于data和flag的寫入,如果按照先寫入flag后寫入data的方式進行,或者考慮由于Cache的flush操作的延遲,使得內存中變量的實際修改順序是先flag后data,那么都將導致Thread A的結果不正確。事實上,由于內存讀入操作同樣是可能亂序進行的,Thread A甚至可能在讀入flag進行判斷之前就已經完成了對data的讀入操作,這同樣導致錯誤的結果。 Solution
在這個例子中,我們的需求是,Thread A中對于flag判斷時,后面的任何讀入操作都沒有開始,Thread B中對于flag寫入時,任何之前的寫入操作都已經完成。
在Linux內核中,smp_rmb()、smp_wmb()、smp_mb()就是用來解決這類問題的,mb表示memory barrier。rmb表示讀操作不可跨越(注意,不是人民幣的意思:-P),也就是我們這個例子中的Thread A所需要的。wmb表示寫操作不可跨越,也就是這里Thread B所需要的。mb集合了rmb和wmb的能力,讀寫操作都不可跨越。
在Qt中,其支持原子操作的類QAtomicInt支持四種類型的操作,Relaxed、Acquired、Release、Ordered,其中 Relaxed最為簡單,就是不做特殊要求,由編譯器和處理器對讀寫進行合適的排序。Acquired表示原子操作之后的內存操作不可被重排至原子操作之前。Release表示原子操作之前的內存操作不可被重排至原子操作之后。Ordered表示Acquired + Release。在前面的例子中,Thread A對于flag的讀取操作需要Acquired版本,而Thread B對于flag的寫入操作需要Release版本。
在實際實現中,不同體系結構的實現方法各不相同,很多RISC機器提供了專門的指令用于實現mb,而在x86上面,通常使用lock指令前綴加上一個空操作來實現,注意當然不能真的是nop指令,但是可以用來實現空操作的指令其實是很多的,比如Linux中采用的addl $0, 0(%esp)。Qt的不同類型原子操作由于本身就需要進行某種可被lock前綴修飾的操作,所以就不需要畫蛇添足的再寫一條空操作了,比如 testAndSetOrdered就可以直接使用lock cmpxchgl實現。

?

轉貼自:http://etrnlog.appspot.com/2009/10/12/memory-ordering.html

轉載于:https://www.cnblogs.com/codingmylife/archive/2010/04/28/1722573.html

總結

以上是生活随笔為你收集整理的Memory Ordering的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。