Latch的spin及sleep(zt)

zhouwf0726發表於2019-02-27
spin=>當一個process要求一個latch,因為某種原因,導致無法取得該latch。這時process會要求進行spin動作(即cpu進行一種­類似空轉的動作),當這次spin完成後,在試圖要求latch一次,若還是無法取得,再進行一次spin。_spin_count是最多可以進行幾次spin­動作。事實上spin主要原因,我想是因此process在被分配到的cpu
time中,若一次無法取得latch,便讓出cpu
time,這樣太浪費好不容易取得的cpu
time,所以使用spin的技巧,繼續佔用cpu
time,希望過一會,所需要的latch已經被別的process釋放了。
所以如果在單cpu系統中,spin是無用的,因為沒有其他的cpu可以用來釋放latch,因此_spin_count=1。
但若是多cpu系統中,_spin_count=2000(default),因為sleep必須讓出cpu
time,而cpu必須進行context
switch,以及重新排程processes的動作,這個成本比spin大得多。所以spin動作在多cpu環境下,才有用。
如果持續spin,spin次數>_spin_count時,這時process便必須讓出cpu
time,而process進入sleep狀態。
Sleep=>表示process在等待latch
free的事件,一開始process會sleep,大約0.01秒,睡醒後,又再要求latch。若依然無法取得latch,之後每次sleep時間,便增加­為上一次sleep時間的兩倍,如此延長sleep時間,最大一直到_max_exponential_sleep所設定的值,預設是2秒。

latch=>在一般的OS是利用memory中的某個位置,藉由將值設定為0或非0,來表示是否已經被取得。
而latch的設計理念,是快速取得而且取得成本低。所以OS的動作通常在很短的時間內完成,而且程式碼通常很短。
因此大多數的OS,是使用test and set的方式來做。

 

Steve Adams 《Oracle8i Internal Services...》

Quote:

3.3.1.1 Why spin?

The idea of spinning is that another process executing on another CPU
may
release the latch, thereby allowing the spinning process to proceed. Of
course, it
makes no sense to spin on a machine with just one CPU, and so Oracle
does not.
The alternative to spinning is to relinquish the CPU and allow another
process to
use it. At first glance, this may seem like a good idea. However, for a
CPU to stop
executing one process and begin executing another, it must perform. a
context
switch . That is, it must save the context of the first process,
determine which
process to schedule next, and then resume the context of the next
process. The
context of a process is essentially a set of CPU register values that
describes the
exact state of the process.
The implementation of context switches is highly machine dependent. In
fact, it
is typically written in assembly language. System vendors make every
effort to
minimize the size of the context data and optimize context switching by
using
tricks such as remapping memory addresses rather than copying data.
Nevertheless, context switching remains an expensive operation because
various
kernel data structures have to be searched and updated. Access to these
structures is protected by spinlocks, which are the equivalent of
latches for the
operating system. On a large and busy system, context switching
normally
consumes between 1% and 3% of CPU time. So if a context switch can be
avoided
by spinning briefly, then some CPU time can be saved, and the waiting
time to
obtain the latch can be minimized. For this reason, spinning briefly is
normally
preferable to relinquishing the CPU immediately.

 

GETS,MISSES,SLEEPS,SPIN_GETS,SLEEP1-n.

In pseudo code :

   Do_fast_get_latch_routine

   if Latch_acquired then

      GETS := GETS + 1

   else

      Get_count := 0

      While not Latch_acquired then

        Do_slow_get_latch_routine

        if Latch_acquired then

           GETS := GETS + 1
           MISSES := MISSES + 1
           SLEEPS := SLEEPS + Get_count

           Sleep_array [ Get_count ] := Sleep_array [ Get_count ] + 1

           /* Note : If Get_count exceeds maximum array size then just
                     accumulate in the last entry */

           break

        else

           Do_exponential_sleep  -- seeded by Get_count

           Get_count := Get_count + 1

        end if

      end while

The Sleep_array currently has a range of 0 to 11 with 0 corresponding
to SPIN_GETS ( SLEEP0 ) and the rest to SLEEP1-11.

>From the above it can be seen that SLEEPS is the sum of the series of

the
Sleep_array
                   n=max
                 --
                 \
       SLEEPS =   \   SLEEP  x n
                  /        n
                 /
                 --
                   n=1

http://groups.google.com/group/Oracle-Internal/browse_thread/thread/533c794f55a6684c/de716834ca13c944?#de716834ca13c944

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756652/viewspace-412202/,如需轉載,請註明出處,否則將追究法律責任。

相關文章