linux記憶體遮蔽技術

2021-05-27 21:38:30 字數 2257 閱讀 1953

__asm__ __volatile__("": : :"memory");

記憶體屏障(memory barrier)

#define set_mb(var, value) do while (0)

#define mb() __asm__ __volatile__ ("" : : : "memory")

1)set_mb(),mb(),barrier()函式追蹤到底,就是__asm__ __volatile__("":::"memory"),而這行**就是記憶體屏障。

2)__asm__用於指示編譯器在此插入彙編語句

3)__volatile__用於告訴編譯器,嚴禁將此處的彙編語句與其它的語句重組合優化。即:原原本本按原來的樣子處理這這裡的彙編。

4) memory強制gcc編譯器假設ram所有記憶體單元均被彙編指令修改,這樣cpu中的registers和cache中已快取的記憶體單元中的資料將作 廢。cpu將不得不在需要的時候重新讀取記憶體中的資料。這就阻止了cpu又將registers,cache中的資料用於去優化指令,而避免去訪問記憶體。

5)"":::表示這是個空指令。barrier()不用在此插入一條序列化彙編指令。在後文將討論什麼叫序列化指令。

6)__asm__,__volatile__,memory在前面已經解釋

在linux/include/asm-i386/system.h定義:

#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")

7)lock字首表示將後面這句彙編語句:"addl $0,0(%%esp)"作為cpu的乙個記憶體屏障。

8)addl $0,0(%%esp)表示將數值0加到esp暫存器中,而該暫存器指向棧頂的記憶體單元。加上乙個0,esp暫存器的數值依然不變。即這是一條無用的彙編 指令。在此利用這條無價值的彙編指令來配合lock指令,在__asm__,__volatile__,memory的作用下,用作cpu的記憶體屏障。

9)set_task_state()帶有乙個memory barrier,set_task_state()肯定是安全的,但 __set_task_state()可能會快些。

關於barrier()巨集實際上也是優化屏障:

#define barrier() __asm__ __volatile__("": : :"memory")

cpu越過記憶體屏障後,將重新整理自己對儲存器的緩衝狀態。這條語句實際上不生成任何**,但可使gcc在barrier()之後重新整理暫存器對變數的分配。    

例1:1        int a = 5, b = 6;

2        barrier();

3        a = b;

在line 3,gcc不會用存放b的暫存器給a賦值,而是重新讀記憶體中的b值,賦值給a。

例2:它在程序上下文中將乙個元素插入乙個單向鍊錶:

new->next=i->next;

wmb();

i->next=new;

同時,如果不加鎖地遍歷這個單向鍊錶。或者在遍歷鍊錶時已經可以看到new,或者new還不在該鍊錶中。兩個記憶體寫

事件的順序必須按照程式順序進行。否則可能new的next指標將指向乙個無效位址,就很可能出現 oops!

不論是gcc編譯器的優化還是處理器本身採用的大量優化,如write buffer, lock-up free, non- blocking reading, register allocation, dynamic scheduling, multiple issues 等,都可能使得實際執行可能違反程式順序,因此,引入記憶體屏障來保證事件的執行次序嚴格按程式順序來執行。

使用記憶體屏障強加的嚴格的cpu記憶體事件次序,保證程式的執行看上去象是遵循順序一致性模型。在當前的實現 中,wmb() 實際上是乙個空操作,這是因為目前intel的cpu系列都遵循「處理機一致性」,所有的寫操作是遵循程式順序的,不會越過前面的讀寫操作。但是,由於 intel cpu系列可能會在將來採用更弱的記憶體一致性模型並且其他體系結構可能採用其他放鬆的一致性模型,仍然在核心裡必須適當地插入wmb()保證記憶體事件的正 確次序。

記憶體屏障出現因為編譯器或現在的處理器常會自作聰明地對指令序列進行一些處理,比如資料快取,讀寫指令亂序執 行等等。如果優化物件是普通記憶體,那麼一般會提公升效能而且不會產生邏輯錯誤。但如果對 i/o操作進行類似優化很可能造成致命錯誤。所以要使用記憶體屏障,以強制該語句前後的指令以正確的次序完成。其實在指令序列中放乙個wmb的效果是使得指 令執行到該處時,把所有快取的資料寫到該寫的地方,同時使得wmb前面的寫指令一定會在wmb的寫指令之前執行。

linux記憶體遮蔽技術

asm volatile memory 記憶體屏障 memory barrier define set mb var,value do while 0 define mb asm volatile memory 1 set mb mb barrier 函式追蹤到底,就是 asm volatile m...

android遮蔽物理按鍵 電磁遮蔽技術

遮蔽 遮蔽能有效地抑制通過空間傳播的電磁干擾,採用遮蔽的目的有兩種 一 限制內部的輻射電磁能越過某一區域 二 防止外來的輻射進入某一區域 遮蔽按其原理可分為 電場遮蔽的原理 為了獲得良好的電場遮蔽效果,以下幾點必須要注意 磁場遮蔽的原理 磁場遮蔽通常是對直流或極低頻磁場的遮蔽,其效果比對電場遮蔽和電...

linux 訊號遮蔽

include include include include include include sigemptyset newmask 獲取空遮蔽訊號集 sigfillset newmask 獲取遮蔽了所有訊號的遮蔽訊號集,除了那兩個sigkill sigstop sigpending pendma...