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.
the
Sleep_array
n=max
--
\
SLEEPS = \ SLEEP x n
/ n
/
--
n=1
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/756652/viewspace-412202/ ,如需转载,请注明出处,否则将追究法律责任。