天天看點

基于鎖的原子操作

32位ia-32處理器的系統記憶體位址支援基于鎖的原子操作。這些操作通常用于管理共享的資料結構(如信号量,段描述符,系統段,或頁表),在這些資料結構裡,兩個或多個處理器可以嘗試同時修改相同的字段或标志。處理器使用三個互相關聯的機制來實作基于鎖的原子操作:

保證在單處理器下該操作是原子操作。

總線鎖定,使用lock#信号和lock指令字首。

imei(高速緩存一緻性)協定,以確定緩存的資料結構(高速緩存鎖定)可以進行原子操作,這個機制是在奔騰4,英特爾至強和p6系列處理器。

這些機制在以下方面互相依存。一些基本的記憶體事務(如在系統記憶體中讀取或寫入一個位元組)能保證總是被原子的處理。也就是說,一旦某個處理器開始操作某個記憶體位址,處理器保證在其他處理器或總線代理通路記憶體位址之前完成這個操作。為了實作多個記憶體操作(如在共享記憶體區進行讀-修改-寫操作),處理器同時也支援總線鎖定。通常需要以原子的方式進行處理,但處理器不采取自動的方式處理,因為頻繁使用的記憶體往往被緩存在l1 或l2 裡,原子操作通常能在處理器的緩存内部執行,而不使用總線鎖。當對被緩存的記憶體位置執行原子操作時,處理器的緩存一緻性協定保證其他緩存同樣記憶體位置的處理器被妥善的管理。

英特爾486處理器(和更新的處理器)保證以下基本記憶體操作将始終以原子方式進行:

讀取或寫入一個位元組。

讀或寫一個字一個16位邊界上對齊。

讀取或寫入一個32位的邊界上對齊雙字。

奔騰處理器(和更新的處理器)保證以下額外的記憶體操作将始終以原子方式進行:

讀取或寫入一個64位的邊界上對齊的四倍字長。

适合在一個32位的資料總線的16位通路未緩存的記憶體位址。

p6系列處理器(和更新的處理器)保證以下額外的記憶體操作将始終以原子方式進行:

未對齊16 ,32 和64位的通路填充在緩存行中緩存。

如果通路緩存被分成不同的高速緩存行和頁邊界裡,将不保證是原子性。英特爾酷睿2雙核,英特爾®淩動™處理器intel酷睿,雙核,奔騰4,奔騰m,英特爾至強處理器,p6系列,奔騰,intel486處理器,英特爾core 2 duo處理器,英特爾淩動,英特爾酷睿,奔騰m,奔騰4,英特爾至強,和p6系列處理器提供總線控制信号允許外部記憶體的子系統使分裂通路原子,但是非對齊的資料通路嚴重影響性能的處理器,應該避免。一個x87指令或一個sse指令實作多個存儲器的通路比用四字實作要大。如果這樣的指令存儲在記憶體裡,一些通路(寫記憶體)或許能夠完成,當另外一個操作因為架構原因失敗。(例如,由于一個頁表項故障被标記為“不存在”)。

英特爾64和ia-32處理器提供了一個lock#信号,這個信号在某些關鍵的記憶體操作時自動發出鎖定系統總線或等價鍊路。當此輸出信号被發出時,從其它處理器或控制總線代理的請求會被阻塞。軟體可以指定其他的場合時,lock

語義應遵循在前面加上lock字首的指令。

在英特爾386,英特爾486和奔騰處理器,顯式鎖定的情況下,說明會導緻發出lock#信号。它的責任是硬體設計者在系統硬體中使用lock#信号控制處理器中記憶體通路。

對于p6和更新的處理器家族,如果被通路的記憶體區域是處理器内部緩存,一般不主張發出lock#信号,相反,鎖定隻适用于處理器的高速緩存。

(譯者注:以上三個小節未翻譯,有興趣的朋友可以幫忙補充下)

在英特爾486和奔騰處理器裡,即使被鎖定的記憶體區域是緩存在處理器中,lock#信号在lock操作期間總是聲言在總線上。

在p6和最近的處理器中,如果在鎖操作期間,已經緩存在處理器緩存行的記憶體區域執行鎖操作回寫記憶體,處理器不會在總線上聲言lock#信号。相反地,它會修改内部記憶體位址,并使用緩存一緻性機制來確定執行的原子性,此操作被稱為“緩存鎖定”,緩存一緻性機制會阻止同時修改被兩個以上處理器緩存的記憶體區域資料。