From: rec@aim.com (Bob Cousins)
Subject: Re: Solaris (was: Sun 600MP Benchmark Anomaly)
Organization: /usr/lib/news/organization
Date: Mon, 27 Jul 1992 18:20:52 GMT

In article <nodh0gc@rhyolite.wpd.sgi.com> vjs@rhyolite.wpd.sgi.com (Vernon Schryver) writes:
>In article <1992Jul25.142435.9821@athena.mit.edu>, jfc@athena.mit.edu (John F Carr) writes:
>> In article <14pkdrINN5ni@uk-news.UK.Sun.COM>
>> 	adrian.cockcroft@uk.sun.com writes:
>> How much of the 95% is spent in the locking code?  How much is spent
>> waiting for locks?
>You must have see some of the some MP UNIX kernel implementations, and
>wondered how they get anything done what with all of the locking and
>P'ing and V'ing.

This brings up an important point! There is a relationship between
CPU speed, number of CPUs and the "desireable granularity" of locks.
When one has a large number of faster CPUs and a mechanism to quickly
handle the common case of no contention for a lock, very fine-grained 
locking can be optimal. However,the overhead  of the 
system by adding locks must be viewed as a cost/benefit decision.
Just because one *CAN* do fine grained locking, does not mean that
it will result in better performance or *SHOULD* be done.

Case in point: Years ago, I was in charge of architecting a series
of Z80 based multiprocessor machines. All code was written in a 
reentrant fashion in assembly language (this was a long time ago).
It quickly became apparent that there was an "optimal granularity"
for semaphore locking. If the granularity became too small, the
system wasted too much time doing semaphore operations (about 10
instructions in the successful case). If the granularity became
too large, contention caused decreases in performance as more
and more "large" locks began to gate tasks.

The next hardware generation used 80186s but functionally identical
technology. It became apparent that the locking strategies
which were ideal for Z80s were too coarse grained for the '186.
By adding more locks (about 2x if my memory is right) we reached
the optimal point. The '186 seemed to be about 4 or 5 times faster
than the Z80. (I'm sure there is a PhD thesis in this area just
waiting to be written!)

The final solution was to rewrite the code so that fewer locks
were needed. (It seems that so many immature implementations 
are based upon lock-crazy designs.) By careful coding, we were
able to substantially reduce the need for locks through atomic
updates, pointer traveling techniques and a number of similarly
simple changes. In one case, we were able to eliminate all but 
one semaphore in a disk driver which covered a small code region
which modified device registers. The result was a virtually 
contention free driver which had substantially reduced overhead.
The code was cleaner, faster, smaller and in all important metrics
better.

The point I'm trying to make is simple: the degree of granularity
which provides *MAXIMUM* performance varies from system to system
(and will likely be a source of tweaking throughout the life of the
code). As machines scale, the optimal locking scheme will change.
The best solution, both short term and long term, is to avoid locking 
whenever possible. IMHO, many locks can be avoided. The use of locks 
should be viewed as a necessary evil and almost as an implementational 
failure. 

BTW: we eventually worked out a scheme to deal with hardware registers
which avoided all need for semaphores in the common case. It required
some unusual hardare features but it worked.



-- 
________________________________________________________________________________
Robert Cousins                    rec@aim.com                  (408)748-8649x212
Consultant to Aim Technology                          Speaking for myself alone.