驅動開發基礎 併發 競態 編譯亂序 執行亂序

2021-08-20 05:45:19 字數 1294 閱讀 7010

併發:多個執行單元同時、並行被執行

競態:多個併發的執行單元對同一共享資源的訪問

競態產生的條件:

1.單處理器中低優先順序的程序被高優先順序的程序搶占,同時他們訪問同一塊共享資源

2.多處理器中,cpu1的程序、cpu2的程序同時訪問同一塊共享資源

3.上述兩種情況下,中斷打斷程序的執行,同時中斷也訪問同一塊共享資源;甚至中斷被更高優先順序的中斷打斷,兩者同時訪問同一塊共享資源...

解決競態問題的途徑是保證對共享資源的互斥訪問。

可採用的互斥機制有:中斷遮蔽、原子操作、自旋鎖、訊號量、互斥體...等

編譯亂序:現代高效能編譯器在目標**的優化上都具備對指令進行亂序優化的能力(編譯器可以對訪存的指令進行亂序,減少邏輯上不必要的訪存,以及提高cache命中率和cpu的load/store單元的工作效率)。

執行亂序:高階的cpu可以根據自己快取的組織特性,將訪存指令重新排序執行。連續位址的訪問可能會先執行,因為這樣的快取命中率高。有的還允許訪存的非阻塞,即如果前面一條訪存指令因為快取不命中,造成長延遲的儲存訪問時,後面的訪存指令可以先執行,以便從快取中取數。

因此,即使是在彙編**上看順序正確的指令,實際執行是的順序也是不可預知的。

我對這塊內容的理解是這樣的:為了加快cpu的執行速度,所以需要使用cache(cache就是快取,訪問速度介於cpu暫存器和記憶體之間,因為記憶體的訪問速度遠小於cpu執行速度,會大大拖累cpu的執行效率,因此大牛們設計出了快取這一概念,它的作用就是將記憶體中的一部分內容放到快取內,cpu訪問記憶體前先查詢快取中是否有這個資料,如果有,直接從快取中獲取,如果沒有,再去記憶體中獲取,這樣的設計大大提高了cpu的執行效率)但是這樣還有乙個問題!如果每次cpu想要獲取的資料,cache中都沒有,那就很悲催了;因此,硬體大牛們又對cpu做了一系列的優化:編譯亂序和執行亂序,這兩貨的終極作用就是對指令進行合理的排序,從而增加cache命中率。目的就是為了增加cache命中率!

再提一下cache,cache的工作就是,當你訪問一塊記憶體位址時,cache會將這個記憶體位址+記憶體位址前後的一段區域內的資料都快取到cache中,為什麼?因為大量的實驗研究表明,下一次cpu訪問記憶體位址很大可能會在之前記憶體位址的前後附近。因此,cache會把他們快取,如果沒有命中(cpu訪問的記憶體位址是其他位址),則cache會重新快取那塊位址的前後一段區域內的資料。

在實際的編碼過程中,我們寫的有些**,並不希望被這麼高階的cpu給優化掉,可以通過記憶體屏障的方式,保護我們的**不被編譯器優化,不被cpu優化。

為什麼講這一塊內容呢?因為...在保護共享資源的互斥機制中,自旋鎖、互斥體等互斥邏輯都考慮到了編譯優化和執行優化,也都做了記憶體屏障保護這塊**不被優化

併發與競態

linux是乙個多工的作業系統,在多個程序同時執行時,就有可能為了競爭同乙個資源發生堵塞。以下是解決的幾種方法 1 訊號量 declare mutex sem if down interruptible sem critical section up sem 2 完成量 declare comple...

LDD 併發和競態

1.正在執行的多個使用者空間程序可能以一種令人驚訝的組合方式訪問我們的 2.smp系統甚至可在不同的處理器上同時執行我們的 3.核心是可搶占的,驅動程式 可能在任何時候丟失對處理器的獨佔 4.裝置中斷時非同步事件,可能導致 的併發執行 5.核心還提供了許多可延遲 執行的機制,比如workqueue ...

Linux中的併發和競態

本帖大體上描述linux kernel為解決併發導致的競態所提供的核心api 主要是訊號量和自旋鎖 之間的區別,側重於使用方面。級的閱讀比較打算另開一貼。因為程式的併發執行而導致的競態是linux核心中乙個非常複雜的方面。對於裝置的驅動程式開發者而言,熟悉linux核心提供的併發互斥的處理機制相當重...