1. 程式人生 > >硬體對同步的支援-TAS和CAS指令

硬體對同步的支援-TAS和CAS指令

[TOC] 現在主流的多處理器架構都在硬體水平上提供了對併發同步的支援。 今天我們討論兩個很重要的硬體同步指令:Test-and-Set和Compare-and-Swap ##Test and Set 一個Test-and-Set(TAS)指令包括兩個子步驟,**把給定的記憶體地址設定為1,然後返回之前的舊值。** 這兩個子步驟在硬體上實現為一個**原子操作**,執行期間不會被其他處理器打斷。 (一個CPU可以使用諸如Dual-port RAM電子原件提供的TAS指令,此外,CPU自身也可以提供CAS指令) **值得注意的是,TAS指令是在1位(bit)上實現,這限制了變數非0即1,不會有其他值,並且TAS總是把變數設定為1。** 可見,TAS生而為自旋鎖,下面是使用TAS實現自旋鎖的虛擬碼[2]: ``` lock = 0 //shared state while(test_and_set(lock)==0){ //try lock //do nothing } // 臨界區程式碼 lock = 0 //release ``` 當第一個執行緒執行這段程式碼時,TAS指令會立即把lock設定為1,並返回0 ,執行緒退出while迴圈進入臨界區。 如果另一個執行緒嘗試進入臨界區,TAS會把lock設定為1,但是也會返回1(由第一個執行緒的TAS指令設定為1), 此時第二個執行緒會一直while迴圈(忙等待),直到第一個執行緒退出臨界區程式碼,執行了lock=0,即釋放了鎖。 這種通過while-loop等待獲取鎖的實現稱為自旋鎖(spin lock)。 ##Compare and Swap compare-and-swap(CAS)指令和TAS指令類似,但是比TAS要更復雜。 與TAS只有一個引數不同,CAS指令需要三個引數,一個記憶體位置(V)、一個期望舊值(A)、一個新值(B)。 CAS指令的執行過程: ``` 1.比較記憶體V的值是否與A相等? 2.如果相等,則用新值B替換記憶體位置V的舊值 3.如果不相等,不做任何操作。 4.無論哪個情況,CAS都會把記憶體V原來的值返回。 ``` 虛擬碼: ``` int CAS(int *ptr,int oldvalue,int newvalue) { int temp = *ptr; if(*ptr == oldvalue) *ptr = newvalue return temp; } ``` 以上過程在CAS指令中是原子操作。 **CAS支援32bit/64bit的資料型別,這使得CAS能夠實現一些更復雜的自旋鎖。** ###使用CAS實現執行緒安全的資料結構。 我們使用CAS實現一個併發的平衡二叉搜尋樹。[1] 基本思路是,所有的更新操作都要在二叉樹的副本上進行,更新完成後,使用CAS指令把新的根節點引用替換舊的引用。 ``` //共享變數 root = pointer to the root of the tree //插入操作 do old_root = root new_root = new Tree # copy old_root into new_root # do insertion into new_root until compare_and_swap (root, old_root, new_root) == old_root 平衡操作: do old_root = root new_root = balanced_copy_of (old_root) until compare_and_swap (root, old_root, new_root) == old_root ``` 如果並行的執行平衡操作和插入操作,插入操作完成後會把二叉樹的根節點指向新的引用。 等到平衡操作完成後,compare_and_swap將會失敗,因為此時根節點指向了插入操作產生的新地址,不再等於old_root, 平衡操作會重複迴圈執行,直到成功更新根節點。 同樣的,如果平衡操作先於插入操作完成,插入操作的CAS指令也會失敗(根節點已指向平衡操作產生的新地址),然後插入操作重複迴圈,直到成功。 基於CAS指令可以實現基礎的訊號量、互斥量之外,還可以實現更復雜的lock-free和wait-free演算法。 **延伸閱讀:** > 1.[康奈爾大學作業系統課件:Architectural support for synchronization](http://www.cs.cornell.edu/courses/cs4410/2015su/lectures/lec06-spin.html) > 2.[wiki:Test-and-Set指令](https://en.wikipedia.org/wiki/Test-and-set) >3.[wiki:Compare-and-swap指令](https://en.wikipedia.org/wiki/Compare-and-swap) >4.[TAS vs CAS](https://stackoverflow.com/questions/3659336/compare-and-swap-vs-test-and-set#:~:text=test%2Dand%2Dset%20modifies%20the,to%20a%20given%20new%20v