Ernest H. Rice III
Proper kernel configuration can make a significant difference
in system
operation. Kernel parameters can, generally, be divided
into two areas:
capacity and performance. This article will focus on
the proper kernel
tuning for system I/O for SCO UNIX systems.
The number of hash buffers (NHBUF)
There may appear to be little difference between the
two sets of
examples, since both quantify some aspect of the kernel.
Also, the two
types of parameters are not necessarily mutually exclusive.
For example,
while NFILE does quantify the capacity for open files,
a truly excessive
value could indirectly impact system performance by
usurping memory
(perhaps causing a system to swap). In normal use, this
would not be the
case, but it does illustrate the importance of understanding
the
underlying effects of each individual parameter.
NMOUNT, which specifies the maximum number of filesystems
(or mount
points) has no real impact on the performance of the
system. It simply
tells the kernel how much space should be reserved,
internally, for the
mount table. A value that is too small will not impact
overall system
performance, it will simply limit the number of filesystems
to be
mounted. Specifying an excessive value for NMOUNT will
only waste
memory, by causing the kernel to reserve space in its
mount table which
will never be used. Again, neither the high nor the
low setting will
impact overall performance (except in the case of a
truly excessive
value, as discussed above).
NBUF, on the other hand, indicates how many buffers
need to be allocated
by the kernel, a quantification, to be sure, one that
has several
ramifications.
If too few buffers are allocated, the system will be
forced to perform
more physical I/O. If the proper number of system buffers
is allocated,
the system has a better chance of satisfying I/O requests
from within
the buffer pool (or cache). Since physical I/O is one
of the most
time-intensive operations performed by the kernel, minimizing
physical
I/O can have a direct impact on the overall system performance.
It's thus important to understand the difference between
kernel
parameters which simply quantify some aspect of the
system, and those
which directly impact the performance of the system.
Moreover, many
kernel parameters have a direct relationship to other
parameters, so
that changing one parameter requires the adjusting of
another parameter,
often in some sort of relationship to the first parameter.
Also, some
parameters limit the effects of others. In this case,
if the limiting
parameter is not changed and the dependent one is, no
effect will be
realized at all.
This article will discuss the interrelationships of
three kernel
parameters used in the optimization of disk I/O. Following
the
guidelines presented in this article will help you minimize
physical
disk I/O and increase overall system performance.
Understanding I/O
Reading or writing of data to any type of media is one
of the most time
consuming of computer operations, because it requires
the interaction of
mechanical equipment. The tape must spin, the disk heads
must move, etc.
If you can minimize the number of physical reads and
writes to media,
you can free up the processor to perform other tasks,
such as executing
instructions, and create the potential for increased
system performance.
Operating systems were designed to take this into account.
A buffer pool
is allocated to hold data read from, or written to,
mass storage
devices. If a record read into the buffer pool is needed
again before
the buffer pool is cleared, no further physical I/O
is required; the
record is simply retrieved from the pool. As the buffer
pool resides in
memory and can be reached without a mechanical operation,
the data can
be retrieved much faster than if a physical I/O had
been required.
A hashing algorithm further improves the performance
of the buffer pool
by reducing the amount of time required to search for
a particular
record within the pool. Once again, proper allocation
of hashing buffers
is critical to optimized performance of the hashing
algorithm. Since the
hashing algorithm has a direct impact on the time required
to retrieve a
record from the buffer pool, ensuring appropriate allocation
of hashing
buffers has a direct impact on optimizing I/O.
Bringing It All Together
When SCO UNIX boots, several kernel parameters are automatically
configured based on the amount of system resources available
at
initialization time. One of these is the number of physical
buffers used
for satisfying I/O requests. This kernel parameter,
NBUF, is gated by
another kernel parameter, MAXBUF. Regardless of what
the kernel believes
is the optimal allocation for system buffers, it will
never exceed the
value specified for MAXBUF. By default, MAXBUF is set
to 600, a value
which often restricts the optimal allocation of system
buffers.
The first step in optimizing the kernel parameters for
physical I/O is
to increase the value for MAXBUF to a level which will
not thwart the
determination of an optimal value for NBUF. To do this,
invoke sysadmsh,
go to the System->Configure->Kernel->Parameters
menu, and select option
1, Disks and Buffers. Cycle through the parameters,
and when MAXBUF
appears, reset it to a large value, say 8192 (8K) to
start with. Once
you have reset this value, rebuild the kernel, using
the sysadmsh menu
option of System->Configure->Kernel->Rebuild.
Rebuild, then reboot the
system.
While the system is rebooting, look at the messages
displayed on the
screen. At or near the bottom, a message will appear
saying something
like:
i/o bufs: XXXX k
This indicates the number of system buffers the kernel
determined was
optimal at boot time. If this value is less than 8192K,
you can proceed
to the next step, otherwise go back to the
System->Configure->Kernel->Parameters menu
of sysadmsh, and increase the
value of MAXBUF again, this time setting it to 16384
(16K). Rebuild the
kernel again, and reboot. Continue this procedure, increasing
MAXBUF
each time, until the message displayed at boot time
indicates that a
value less than the value of MAXBUF is being used for
i/o bufs.
Having determined the optimal value for NBUF, you need
next to adjust
the value used to determine how many hash buffers are
to be allocated.
Note that you need not adjust NBUF by hand, as it is
determined
automatically at boot time by the kernel.
To determine the optimal value for NHBUF, divide the
value displayed at
boot time for the number of i/o bufs by four. Take the
result and round
it up to the next power of two. The resulting value
is what you should
specify for NHBUF. On my system, with 16Mb of memory,
the optimal value
for i/o bufs (as determined by the kernel at boot time),
is 1500K. I
divided this value by four and got 375. I rounded this
value to the next
higher value of two, and got a value for NHBUF of 512.
Once the value for NHBUF has been determined, run sysadmsh
again. Return
to the System->Configure->Kernel->Parameters
menu, select option 1
(Disks and Buffers), and set the new value for NHBUF.
Go to the
System->Configure->Kernel->Rebuild menu of
sysadmsh and rebuild the
kernel.
There is still a little bit of work to do. In the first
step the value
of MAXBUF was inflated to allow the kernel to determine
the optimal
value of NBUF. Once this value was determined, the value
of NHBUF was
set according to the value of NBUF, but MAXBUF is still
at the inflated
value. You could leave it alone, but if you do, and
you add memory
someday, the kernel will dutifully determine a new value
for NBUF at
boot time, and the value for NHBUF which was based on
the old value for
NBUF will no longer be appropriate. This being the case,
it is a good
idea to reset the value for MAXBUF to the value the
kernel displayed for
i/o bufs at boot time. In the example I discussed earlier,
where my
machine displayed a value of 1500, Iwould specify a
value of 1500 for
MAXBUF.
Once again, return to sysadmsh, go to the
Configure->System->Kernel->Parameters menu,
and select Disks and
Buffers. Reset MAXBUF as discussed, and then rebuild
the kernel via the
System->Configure->Kernel->Rebuild menu option.
Reboot the system, and
double-check that the value displayed at boot time for
i/o bufs is still
the value shown earlier. If it is the same value, your
disk I/O should
now be optimized.
Monitoring Buffer Usage
Once the kernel is optimized, you may want to monitor
the usage of the
buffer pool. Ideally, this will show you how effective
the buffer pool
is in reducing costly physical I/O.
Monitoring of most system activity is performed via
the sar(1) command.
sar(1) has many different options, and these can be
very confusing. For
our purposes, the -b option is appropriate. To test
this, enter:
sar -b
This will show you several columns of output. The two
columns of
greatest value for present purposes are those labeled
%rcache and
%wcache. These represent the percentages of read and
write requests,
respectively, which have been satisfied from the cache
(or buffer pool).
The %rcache value should be greater than the %wcache
value, and values
should be in the 90-95% range for %rcache, and in the
80-90% range for
%wcache. If the %rcache value falls below 90% or the
%wcache value falls
below 70%, you should revisit the kernel parameters
for buffer
allocation.
If you run sar(1) soon after the system boots, its output
may be of little value. It is better to run it after
the system has been
up and running for a bit, so that sar(1) has more data
at its disposal,
and thus can offer a more accurate representation of
buffer pool usage.
In addition, when the system is "live," sar(1)
lets you take snapshots
of various aspects of system usage, at periodic intervals.
You could,
for example, see the buffer pool hit ratios every so
many seconds, for a
specified number of intervals. For example, the command:
sar -b 10 20
would run sar(1) every 10 seconds, displaying buffer
information each
time. The command would be repeated 20 times and the
information
displayed would be indicative of buffer usage during
the specified
interval.
Faster Floppy Diskettes
We all have to write to, or read from, floppy diskettes
from time to
time. If you are like me, you've often wished these
procedures could run
a little faster. Here is a simple tip that can reduce
your floppy
diskette transfer time.
When you format a floppy diskette, specify an interleave
of two. The
default interleave is one, and although compatible with
MS-DOS, the
value of one is less than optimal. Try it. If you are
using a 3.5-inch
high density diskette, enter:
format -i2 /dev/rdsk/f03ht
The resulting diskette should have better performance
than one formatted
without the -i2 option. Everything comes with a price;
however. The
diskettes formatted with an interleave of two will most
likely have to
be reformatted with an interleave of one if they are
ever to be read on
an MS-DOS system.
Although most diskette drives should be able to read
from or write to diskettes formatted on another system
using an
interleave of two, if you plan to use these diskettes
on multiple
machines, test one first, as some machines may have
problems reading or
writing to them.
Back It Up!
Finally, since you have reconfigured the kernel, I strongly
recommend
that you create a new set of Emergency Boot and Root
diskettes. You can
do this via the mkdev fd command; the procedure requires
two 3.5-inch
High-Density diskettes.
Conclusion
This article has covered the tuning and monitoring of
three kernel
parameters that can have a dramatic impact on disk I/O
efficiency. Other
kernel parameters also come into play in the optimization
of Disk I/O.
These parameters are more specialized, often geared
to a specific
filesystem type, and, in many cases, will not have as
dramatic an impact
as NBUF, NHBUF, and MAXBUF. However, should you wish
to investigate
these possibilities, take a look at the following parameters: