GENERAL
-------

When System V style shared memory is available, bru can use this
facility to provide double buffering.  The basic idea behind
double buffering is to provide overlapping (simultaneous) I/O to
both the disks and the archive device (typically a tape unit).
Thus for creating archives, files will be read off disk and
placed into archive buffers in memory, while simultaneously
previously created buffers are being written to the tape.
This is accomplished by have bru split into two independent
processes, one which does the disk I/O and one which does
the tape I/O.  If your hardware is not capable of supporting
simultaneous I/O to both the disk and tape devices, then
double buffering will only slow you down.  Unfortunately,
this hardware design flaw seems to afflict a large number of
micro/mini computer systems, particularly those with all
the peripherals attached via a single SCSI bus.

IMPORTANT PARAMETERS
--------------------

To discuss tuning of the shared memory system as used by
bru, we need to define the following parameters:

shmmax		This is the maximum size of any single shared
		memory segment as used by bru.  The absolute
		upper limit on this value is set by the
		kernel (the SHMMAX parameter in the kernel
		config file).

		Additionally, an artificial limit can be imposed
		on a per device basis by defining a value in the
		brutab entry for the device (shmmax=64Kb for
		example).  If a brutab value is not specified,
		a default value is picked by bru.  This value
		is compiled into bru and is set by the B_SHMMAX
		parameter in bru's config.h source file.

shmseg		This is the maximum number of shared memory
		segments which are used by bru.  Note that
		bru uses one segment for shared variables,
		and the rest for archive buffers.  Thus
		the absolute minimum value for bru is two.
		The absolute upper limit on this value is set
		by the kernel (the SHMSEG parameter in the 
		kernel config file).

		Additionally, an artificial limit can be imposed
		on a per device basis by defining a value in the
		brutab entry for the device (shmseg=16 for
		example).  If a brutab value is not specified,
		a default value is picked by bru.  This value
		is compiled into bru and is set by the B_SHMSEG
		parameter in bru's config.h source file.

shmall		This is the maximum amount of shared memory
		that will be used by bru.  The absolute upper
		limit on this value is set by the kernel (the
		SHMALL parameter in the kernel config file),
		however, this is a system wide limit.  The
		actual limit per user is roughly the product
		of shmseg and shmmax or SHMALL, whichever is
		smaller.

		Additionally, an artificial limit can be imposed
		on a per device basis by defining a value in the
		brutab entry for the device (shmall=256K for
		example).  If a brutab value is not specified,
		a default value is picked by bru.  This value
		is compiled into bru and is set by the B_SHMALL
		parameter in bru's config.h source file.


GREEDY MODE
-----------

Note that by setting all three of these parameters in your brutab
file to arbitrarily huge values, you can cause bru to operate in
what has been termed "greedy mode".  That is, bru will allocate
as many buffers as it can, and it will make each one of them as
large as it can.  Since this can be terribly wasteful of memory
and seriously impact system performance for other users, the
defaults are much more sensible.  Typical greedy mode parameters
would be {shmseg=1000, shmmax=1M, shmall=1000M}.  The defaults
are usually more like {shmseg=5, shmmax=64K, shmall=320K}.


DETERMINING KERNEL PARAMETERS
-----------------------------

In theory, the best way to determine your absolute maximum limits
as enforced by the kernel is to look up this information in your
kernel config directory or consult your system manuals.  In 
practice, most users are not supplied with, or have access to, the
kernel config files.  Seldom does the documentation mention the
specific values that were used to configure the kernel shipped
with the system.

So, the bru distribution includes a simple program that probes
the shared memory system to try to determine the values dynamically.
A similar facility is incorporated into bru.  To run this program,
locate the executable program "shmtest" and simply run it:

	$ shmtest
	shmseg = 16
	shmmax = 262144 (256K)
	shmall = 2097152 (2048K)
	$


TUNING SHARED MEM FOR A GIVEN DEVICE
------------------------------------

The optimum use of shared memory generally depends on the nature
of the archive device, the hardware configuration, possibly the
version of the operating system, and other assorted variables.
In short, you must test your device in a systematic manner,
to try to determine the optimum parameters to put in the
brutab entry for that device.

Testing consists of setting constraints on bru's shared memory
usage via the brutab entries for shmseg, shmmax, and shmall.
Since bru will naturally try to use as much shared memory as
it can get without violating these constraints.  Reducing shmmax
will cause bru to use smaller buffers, but more of them.  Sort
of like Boyle's law for bru.  (Boyle's law says that for an ideal
gas, the pressure times the volume is a constant, or commonly
paraphrased as "a gas will expand to fill it's container").

By systematically changing shmmax, shmseg, and shmall, bru can
be forced to pick specific values, and thus it's performance
can be measured at each set of values.  The most natural
performance measure is the archive throughput, in Kb/sec.

For a given value of shmmax, measure and plot the throughput
versus the number of shared memory segments.  Each plot of
constant shmmax will give a performance curve which shows
the optimum value for the number of shared segments (the 
smallest number of segments that gives the highest throughput).

Repeat this several times for various values of shmmax.  Since
bru will only use segments that are multiples of the I/O buffer
size, use test values that reflect this relationship.  For
example, the default I/O buffer size for bru is 20Kb.  Thus
the natural test points for constant shmmax would be {20K,
40K, 60K, 80K, 100K, etc}.

Note that running bru with verbosity level four (-vvvv) will
cause it to print the values for the size and number of the
shared memory segments that it selected.  This verifies the
constaints set by changing the brutab shmmax and shmseg 
parameters.

This testing may seem to be (and is) time consuming.  But
depending upon all the hardware and software variables, there
can be dramatic differences in throughput, so the testing
is worthwhile in most cases.
