1. 程式人生 > >原子操作與 x86 上的 lock 指令字首

原子操作與 x86 上的 lock 指令字首

原子操作是不可分割的操作,在執行完畢時它不會被任何事件中斷。在單處理器系統(UniProcessor,簡稱 UP)中,能夠在單條指令中完成的操作都可以認為是原子操作,因為中斷只能發生在指令與指令之間。


在多處理器系統(Symmetric Multi-Processor,簡稱 SMP)中情況有所不同,由於系統中有多個處理器在獨立的執行,即使在能單條指令中完成的操作也可能受到干擾。


在所有的 X86 CPU 上都具有鎖定一個特定記憶體地址的能力,當這個特定記憶體地址被鎖定後,它就可以阻止其他的系統匯流排讀取或修改這個記憶體地址。這種能力是通過 LOCK 指令字首再加上下面的彙編指令來實現的。當使用 LOCK 指令字首時,它會使 CPU 宣告一個 LOCK# 訊號,這樣就能確保在多處理器系統或多執行緒競爭的環境下互斥地使用這個記憶體地址。當指令執行完畢,這個鎖定動作也就會消失。

能夠和 LOCK 指令字首一起使用的指令如下所示:

BT, BTS, BTR, BTC   (mem, reg/imm)
XCHG, XADD  (reg, mem / mem, reg)
ADD, OR, ADC, SBB   (mem, reg/imm)
AND, SUB, XOR   (mem, reg/imm)
NOT, NEG, INC, DEC  (mem)


注意:XCHG 和 XADD (以及所有以 'X' 開頭的指令)都能夠保證在多處理器系統下的原子操作,它們總會宣告一個 "LOCK#" 訊號,而不管有沒有 LOCK 字首。


使用原子操作的一個簡單示例如:
void __fastcall atomic_inc (volatile int* pNum)
{
    __asm
    {
        lock inc dword ptr [ECX]
        ret
    }
}

上面, __fastcall 關鍵字確保引數是通過暫存器來傳遞的,這樣就能夠提升原子指令的效能。

另外,在 linux 核心中有一套原子操作函式,比如其中之一:

static __inline__ void atomic_add(int i, atomic_t *v)
{
    __asm__ __volatile__(
        LOCK_PREFIX "addl %1,%0"
        :"+m" (v->counter)
        :"ir" (i));
}

上面,LOCK_PREFIX 巨集定義了 LOCK 指令字首,如:
#ifdef CONFIG_SMP
#define LOCK_PREFIX \
        ".section .smp_locks,\"a\"\n"    \
        "  .align
4\n"            \
"  .long 661f\n" /* address */    \
".previous\n"            \
"661:\n\tlock; "

#else /* ! CONFIG_SMP */
#define LOCK_PREFIX ""
#endif

由上可見,在單處理器系統下,LOCK_PREFIX 巨集為空,因為此時並不需要 LOCK 指令字首,處理器只要有可能,原子操作就會被編譯成單個機器指令。


在一些處理器,包括 P6 家族,奔騰4(Pentium4)系列,至強(Xeon)處理器,lock 操作可能不會宣告一個 LOCK# 訊號。從 P6 家族處理器開始,當使用 LOCK 指令訪問的記憶體已經被處理器載入到快取中時,LOCK# 訊號通常不會被宣告。取而代之的是,僅是鎖定了處理器的快取。這裡,處理器快取的相干性(coherency)機制確保了可以原子性的對記憶體進行操作。

相關推薦

原子操作 x86 lock 指令字首

原子操作是不可分割的操作,在執行完畢時它不會被任何事件中斷。在單處理器系統(UniProcessor,簡稱 UP)中,能夠在單條指令中完成的操作都可以認為是原子操作,因為中斷只能發生在指令與指令之間。 在多處理器系統(Symmetric Multi-Processor,簡稱

Java並發——原子變量和原子操作阻塞算法

index 復雜 多線程 保護 註意 java並發 edm urn 相同 十五年前,多處理器系統是高度專用系統,要花費數十萬美元(大多數具有兩個到四個處理器)。現在,多處理器系統很便宜,而且數量很多,幾乎每個主要微處理器都內置了多處理支持,其中許多系統支持數十個或數百個處理

gcc原子操作spinlock簡單對比

GCC 提供的原子操作gcc從4.1.2提供了__sync_*系列的built-in函式,用於提供加減和邏輯運算的原子操作。 type __sync_fetch_and_add (type *ptr, type value, ...) type __sync_fetch_

Linux的原子操作同步機制

.html see 原子性 cor 清除 發的 efault 多個 其他 Linux的原子操作與同步機制 轉載自:https://www.cnblogs.com/fanzhidongyzby/p/3654855.html 並發問題 現代操作系統支持多任務的並發,並發在提高計

在有點陣圖索引的表進行DML操作enq: TX - row lock contention等待事件問題分析

在有點陣圖索引的表上進行DML操作與enq: TX - row lock contention等待事件問題分析 前言 模擬場景 總結 前言 本文通過模擬實驗,來分析 有點陣圖索引的表的DML操作 對資料庫造成的

信號燈 ManualResetEvent Interlocked.Increment 原子操作使

ons timeout manage pre 事件 ren void 繼續 args class Program { public static int numb = 0; public static int numbb =

c++11 原子類型原子操作

thread_local automic quick_exit 1、原子類型和原子操作(1)類型(2)操作(3)詳述● 原子類型只能從其模板參數類型中進行構造,標準不允許原子類型進行拷貝構造、移動構造,以及使用operator=等● atomic_flag 是一個原子的布爾類型,無鎖的,即線程對其

Linux驅動開發(13)——併發原子操作

併發 併發的概念 多個執行單元同時、並行被執行。Linux系統是多工的,很多工會同時執行。 假如有三個執行單元ABC,共享了記憶體資源。 執行單元A對Buffer寫1000個“a”; 執行單元B對Buffer寫1000個“b”; 執行單元C從buffer中讀取資料。 如果按照

讀HDFS書筆記---5.2 檔案讀操作輸入流(5.2.2)---

5.2.2 讀操作--DFSInputStream實現    HDFS目前實現的讀操作有三個層次,分別是網路讀、短路讀(short circuit read)以及零拷貝(zero copy read),它們的讀取效率一次遞增。 網路讀: 網路讀是最基本的一種HDFS讀

鎖機制原子操作

一、執行緒同步中的一些概念   1.1臨界區(共享區)的概念   在多執行緒的環境中,可能需要共同使用一些公共資源,這些資源可能是變數,方法邏輯段等等,這些被多個執行緒共用的區域統稱為臨界區(共享區),臨界區的資源不是很安全,因為執行緒的狀態是不定的,所以可能帶來的結果是臨界區的資源遭到其他

【nginx原始碼】nginx中的鎖原子操作

問題引入 多執行緒或者多程序程式訪問同一個變數時,需要加鎖才能實現變數的互斥訪問,否則結果可能是無法預期的,即存在併發問題。解決併發問題通常有兩種方案: 1)加鎖:訪問變數之前加鎖,只有加鎖成功才能訪問變數,訪問變數之後需要釋放鎖;這種通常稱為悲觀鎖,即認為每次

順序性,一致性,原子性:現代多核體系結構原子操作·CAS自旋鎖·自旋鎖併發程式設計的原語·語句原子性和程式設計邏輯的原子性·行鎖資料庫事務原子性·binlog資料庫同

順序性: 亂序執行·邏輯正確性  現代體系結構的每一個核的指令流水是亂序執行的,但是他能夠保證其執行效果正確,即等同於順序執行。 不過這帶來的問題是對於一個核在主觀上它的執行狀態最終保證正確,但是對於別的核,如果在某一箇中間時間點需要觀察它呢?看到的是一個不正確的

C++11原子型別原子操作

1.認識原子操作 原子操作就是在多執行緒程式中“最小的且不可並行化的”操作,意味著多個執行緒訪問同一個資源時,有且僅有一個執行緒能對資源進行操作。通常情況下原子操作可以通過互斥的訪問方式來保證,例如Linux下的互斥鎖(mutex),Windows下的臨界區(Critical Sec

linux原子操作實現lock鎖功能

轉載請註明:http://blog.csdn.net/fuqiangnxn/article/details/53942136 int g_intlock = 0; //鎖變數 //下面程式碼為實現鎖的功能 int ivalue; while(1) {     ivalue

Intel硬編碼(一):Opcode Map、定長指令指令字首

Intel CPU(基於P6微架構)的機器指令(硬編碼)格式如下圖所示: 一條指令由:**指令字首(Instruction Prefixes) + 操作碼(Opcode) + ModR/M + SIB + 偏移(displacement) + 立即數(Imme

Java併發程式設計(八)------無鎖無鎖類(原子操作類)

1. 無鎖的概念 無鎖主要有兩個特徵: 是無障礙的 保證有一個執行緒可以勝出 與無障礙相比,無障礙並不保證有競爭時一定能完成操作,因為如果它發現每次操作都會產生衝突,那它則會不停地嘗試。如果臨界區內的執行緒互相干擾,則會導致所有的執行緒會卡死在臨界區,那麼系統性能則

[通俗易懂] ARMX86不具備可比性 效能差距可大千倍

這裡就不去管細節,簡單來談一下,ARM和X86之間為什麼不太具有可比性的問題。要搞清楚這個問題首先要明白什麼是架構,之前也有很多人提到了架構不同,但架構是什麼意思?它是一個比較抽象的概念,不太容易用幾句話就解釋清楚。 我們要明白CPU是一個執行部件,它之所以能執行,也是因

單核、多核鎖、同步操作原子操作

(1)      所有的同步操作最基礎的理論就是原子操作,記憶體屏障、鎖都是為了保證在不同平臺或者cpu下的原子操作。 記憶體屏障作用: A:在編譯時,拒絕編譯器優化之後的指令 B:在執行時,告訴記憶體地址匯流排,共享資料地址必須同步 鎖是記憶體中一種整型資料,只有兩種狀

HTTP斷點續傳斷點傳之 -- 檔案流操作

不管是下載還是上傳,斷點的時候,就需要對檔案流進行精確的操作。 1、下載斷開了,已經下載的資料儲存到檔案,再次繼續下載的時候需要從檔案的尾巴繼續追加資料; 2、同理上傳也是一樣,http通訊中有可能斷開或者丟包的情況,就需要重傳指定的檔案片; 我封裝的這個

原子操作、訊號量、讀寫訊號量和自旋鎖的區別聯絡

一.為什麼核心需要同步方法 併發指的是多個執行單元同時,並行被執行,而併發的執行單元對共享資源(硬體資源和軟體上的全域性變數,靜態變數等)的訪問則很容易導致競態。 主要競態發生如下: 1.對稱多處理器(SMP)多個CPU  SMP是一種緊耦合,共享儲存的系統模型,它的特點是多個CPU使用共同的系統匯流排,因此