簡體   English   中英

什么是處理器 Lock# 信號以及它是如何工作的?

[英]What is processor Lock# signal and how it works?

我正在閱讀一本關於匯編(中級)的書,它提到像xchg這樣的一些指令會自動斷言處理器 LOCK# 信號。 在網上搜索它發現它賦予處理器任何共享 memory 的專有權,但沒有具體細節。 這讓我想知道這項權利是如何運作的。

  1. 這是否意味着任何其他計算機設備(例如 GPU 或其他設備)都無法訪問 memory。 實際上,其他設備可以直接與 RAM 對話,而無需先通過 CPU。
  2. 處理器如何知道它在這個鎖定的 state 中是否保存在控制或 rflags 寄存器中,或者因為我看不到在擁有多核 CPU 時這個操作是如何工作的。
  3. 我訪問的網站說鎖定任何共享 memory 這是否意味着在此鎖定期間整個 RAM 被鎖定或僅鎖定執行指令的 memory 頁面(或 memory 的一部分而不是全部)。

基本問題是有些指令讀取memory,修改讀取的值,然后寫入新的值; 如果 memory 的內容在讀取和寫入之間發生變化,(某些)並行代碼可能會導致 state 不一致。

一個很好的例子是一個 CPU 執行inc dword [foo]而另一個 CPU 執行dec dword [foo] 兩條指令(在兩個 CPU 上)都執行后,值應與原來相同; 但是兩個 CPU 都可以讀取舊值,然后兩個 CPU 都可以修改它,然后兩個 CPU 都可以寫入它們的新值; 導致該值比您預期的高 1 或低 1。

解決方案是使用#lock信號來防止其他任何東西同時訪問同一塊 memory。 例如,第一個 CPU 將斷言#lock然后執行它的讀取/修改/寫入,然后取消斷言#lock 並且其他任何東西都會看到#lock被斷言並且必須等到#lock被取消斷言才能執行任何memory訪問。 換句話說,它是一種簡單的互斥形式(如自旋鎖,但在硬件中)。

當然,“其他一切都必須等待”有性能成本; 所以它主要只在軟件明確請求時完成(例如lock inc dword [foo]而不是inc dword [foo] ),但在少數情況下它是隱式完成的 - 當操作數使用 memory 時的xchg指令,並更新到dirty/ CPU 使用的某些表中的已訪問/忙碌標志(用於分頁和 GDT/LDT/IDT 條目)。 還; 后來(我認為是 Pentium Pro?),該行為被優化為與緩存一致性協議一起使用,因此如果緩存行可以放在專用的#lock中,則不會斷言 #lock 。

注意:過去有 2 個 CPU 錯誤(Intel Pentium "0xF00F" 錯誤和 Cyrix "Coma" 錯誤),其中一個 CPU 可以被欺騙斷言#lock信號並且從不取消斷言; 導致整個系統鎖定,因為沒有任何東西可以訪問任何 memory。

  1. 這是否意味着任何其他計算機設備(例如 GPU 或其他設備)都無法訪問 memory。 實際上,其他設備可以直接與 RAM 對話,而無需先通過 CPU。

是的。 如果#lock被斷言(不包括較新的 CPU 可以將緩存線放入獨占 state 的情況); 任何訪問 memory 的東西都必須等待#lock被取消斷言。

注意:大多數現代設備可以/確實直接訪問 memory(在不使用 CPU 傳輸數據的情況下將數據傳輸到 RAM 或從 RAM 傳輸數據)。

  1. 處理器如何知道它在這個鎖定的 state 中是否保存在控制或 rflags 寄存器中,或者因為我看不到在擁有多核 CPU 時這個操作是如何工作的。

它不保存在任何寄存器的內容中。 它實際上是公共汽車或鏈路上的電子信號。 舉一個極其簡單的例子; 假設總線有 32 條“地址”線,32 條“數據”線,加上#lock線; 其中“斷言#lock ”表示該#lock線上的電壓從0 伏到3.3 伏。 當任何東西想要讀取或寫入 memory(在嘗試更改“地址”線或“數據”線上的電壓之前)時,它會檢查#lock線上的電壓是否為 0 伏。

注意:真正的總線要復雜得多,需要一些其他信號(例如傳輸方向、避免沖突、“I/O 端口或物理內存”等); 現代公共汽車使用串行通道而不是並行線; 現代系統使用“點對點鏈接”而不是“所有事物共享的公共總線”。

  1. 我訪問的網站說鎖定任何共享的 memory。 這是否意味着在此鎖定期間整個 RAM 被鎖定或僅鎖定執行指令的 memory 頁面(或 memory 的一部分而不是全部)。

不如說公交車上鎖了; 一切都必須使用總線來訪問 memory (當總線被鎖定時,沒有其他東西可以使用總線,即使其他東西試圖將總線用於與 memory 無關的事情 - 例如發送一個 IRQ 到CPU)。

當然(由於積極的性能優化 - 主要是“如果緩存行可以放在專有的 state 中”優化)更好的是說硬件可以做任何感覺只要結果表現得好像有被鎖定的共享總線(即使沒有共享總線並且實際上沒有任何東西被鎖定)。

注意:80x86 支持未對齊的訪問(例如,您可以lock inc dword [address] ,其中訪問可以跨越邊界),如果 memory 訪問確實跨越邊界,則 CPU 需要組合 2 個或更多片段(例如,從一個高速緩存行的結尾和從下一個高速緩存行開始的幾個字節)。 現代虛擬 memory 意味着如果虛擬地址跨越頁面邊界,則 CPU 需要訪問 2 個不同的虛擬頁面,這些頁面可能具有“極其不相關”的物理地址。 如果理論上的 CPU 嘗試實現獨立鎖(每個 memory 區域的不同鎖),那么它還需要支持斷言多個鎖信號。 這可能會導致死鎖——例如,一個 CPU 鎖定“內存頁面 1”,然后嘗試鎖定“內存頁面 2”(並且不能因為它被鎖定); 而另一個 CPU 鎖定“內存頁面 2”然后嘗試鎖定“內存頁面 1”(並且不能因為它被鎖定)。 要解決這個問題,理論上的 CPU 必須使用“全局鎖排序”——始終以特定順序斷言鎖。 最終結果將是大量的復雜性(增加的復雜性可能會花費更多的性能而不是節省的性能)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM