看jemalloc看到這個函數,不解,搜了下並轉到這裏
這個api名字夠長,我喜歡!
實際上對 CRITICAL_SECTION 的操作非常輕量,爲什麼還要加上旋轉鎖的動作呢?其實這個函數在單cpu的電腦上是不起作用的,只有當電腦上存在不止一個cpu,或者一個cpu但多核的時候,才管用。
如果臨界區用來保護的操作耗時非常短暫,比如就是保護一個reference
counter,或者某一個flag,那麼幾個時鐘週期以後就會離開臨界區。可是當這個thread還沒有離開臨界區之前,另外一個thread試圖進入
此臨界區——這種情況只會發生在多核或者smp的系統上——發現無法進入,於是這個thread會進入睡眠,然後會發生一次上下文切換。我們知道
context
switch是一個比較耗時的操作,據說需要數千個時鐘週期,那麼其實我們只要再等多幾個時鐘週期就能夠進入臨界區,現在卻多了數千個時鐘週期的開銷,真
是是可忍孰不可忍。
所以就引入了InitializeCriticalSectionAndSpinCount函數,它的第一個參數是指向cs的指針,第二個參數
是旋轉的次數。我的理解就是一個循環次數,比如說N,那麼就是說此時EnterCriticalSection()函數會內部循環判斷此臨界區是否可以進
入,直到可以進入或者N次滿。我們增加的開銷是最多N次循環,我們可能獲得的紅利是數千個時鐘週期。對於臨界區內很短的操作來講,這樣做的好處是大大的。
MSDN上說,他們對於堆管理器使用了N=4000的旋轉鎖,然後“This gives great performance and scalability in almost all worst-case scenarios.” 可見還是很有用的:-)
http://yjl.spaces.live.com/blog/cns!8129C4219A8E995B!466.entry