Topic "mapping"

MAPPING			Monash Image Library                        MAPPING

The image library supports the mapping of raw format image files (i.e.
format img, smg etc) directly into the address space of applications via the
mmap(2) system call.  For simple image update operations which visit each
pixel once only, mapped images can be processed up to 3 times faster as I/O
buffering is avoided altogether.  For applications which visit only a few
pixels, mapped images can be processed in constant time rather than in time
proportional to the image size.  By default only a portion of a mapped image
is mapped at any one time (i.e. images are cached). This allows huge images
to be processed (with sequential or very simple access patterns) using only
a small amount of virtual (and hence physical) memory.

Images can be mapped for read only, private, or read/write access. The
environment variable I_MAPPING is used to turn mapping on and set the
default access mode, e.g. (csh or tcsh):

	setenv I_MAPPING I_RDONLY
	setenv I_MAPPING I_PRIVATE
	setenv I_MAPPING I_RDWR

If the environment variable I_MAPPING is defined and does not have any value
or has an invalid value then a warning is issued and read only mapping mode
is used.  When an image is mapped for read/write access then it is not
necessary to use i_dump to write out the image, it is done automatically (at
the virtual memory management system's leisure on SGI hardware); with DEC
hardware you must call i_close to ensure that last altered region is written
out. Intel hardware should use i_close to ensure it is written.

When an image is mapped for private access you can still alter pixels (i.e.
via i_putpix etc) but the changes will not be made automatically to the
original file, a private copy of the altered pages is kept for your process
and you must use i_dump to output the altered image.  Since the private
pages are lost when a span is remapped, this mode is only recommended with a
span of 0 (see below).  When an image is mapped for read only access then
attempts to write pixels will cause a segmentation violation Both read only
and private mapping modes cannot alter the original image file under any
circumstances.

The default access mode can be overridden by means of the procedures declared
as follows:

	void i_mapping(int flags);
	void i_no_mapping();
	int i_get_mapping();
	int i_get_mapping_flags();

where the access mode is specified for i_mapping (i.e. i_mapping(I_RDONLY)
or i_mapping(I_RDWR), i_no_mapping turns mapping off, i_get_mapping returns
the current mapping on/off state (0 means off) and i_get_mapping_flags
returns the current mapping access mode.  The mapping mode and flags are
inspected when an image is opened and these values remain in effect for that
image until it is closed.  Hence it is not possible to change the mapping
parameters of an open image. In the future some of the image library
commands (e.g. iinfo) will use mapping by default (i.e. regardless of the
I_MAPPING environment variable or calls to i_mapping).  This will only be
done when the use of mapping is operationally indistinguishable (apart from
efficiency) from unmapped access.

IMPORTANT NOTE:

If a source file uses macros for pixel access (i.e. "#define FAST" before
including image.h) then a separate set of macros must be nominated by also
defining the symbol REMAP_ON_FLY before the include.  If FAST is not defined
then REMAP_ON_FLY is ignored.

The rest of this help file concerns steadily more detailed descriptions and
fine tuning of mapping parameters.  It need only be read if mapping does not
appear to be working as expected or the ultimate in efficiency is required.

Two important mapping parameters are modifiable: the mapping span and the
mapping prelude.  The span indicates the size of the mapped block as a
number of image rows.  The default value is 32.  If a span of 0 is specified
then all the rows are mapped.  If the span value is too large it may be
counterproductive on some machines since the whole span is flushed out and
the new span read in each time there is a "miss".  On some machines the
image is paged in and out so this is not a problem.  If the span is too
small then an inefficiency arises due to the mapping swap unit being a page
which is likely to be several rows for small images. To avoid this
inefficiency the span is automatically rounded up to the highest value which
cannot increase the number of pages in the span, however there is still a
residual inefficiency due to partially mapped rows at each end of the span
(mapped regions of files must be page aligned).

The prelude is best explained with an example.  If the span is 16 and the
first pixel accessed is in row 0 then the first 16 rows will be mapped into
the address space.  If the next access is in row 17 then rows (16 - prelude)
to (31 - prelude) will be mapped into the address space.  Hence the prelude
is the number of rows mapped prior to the "missed" row.  This is to avoid
thrashing when doing image processing operations which look at the
neighbourhood of every pixel.  The default prelude is 1 (i.e. one row prior
to the current row is mapped if possible).  When the rows to be mapped
extend before or beyond the valid rows of the image the mapped region is
pushed forward or pulled back to map a span of valid rows.  This explains
why the first pixel access mapped rows 0 to 15.  N.B. in this example the
optimality feature of rounding up the number of rows in a span while still
fitting into the same number of pages was ignored.

Control of span and prelude is via environment variables I_SPAN and
I_PRELUDE, e.g. (csh):

	setenv I_SPAN 100
	setenv I_PRELUDE 0

and procedures:

	void i_set_mapping_span(int span);
	int i_get_mapping_span();
	void i_set_mapping_prelude(int prelude);
	int i_get_mapping_prelude();

If you have an access pattern that alternates accesses of an image between
two regions (for example comparing every pixel with every other pixel) then
the use of a single mapped image for this access pattern will thrash the
cache.  One way around this (if read access is all that is required) is to
map the image twice (i.e. open it twice using separate IMAGE pointers) and
use one alias for each region.  Otherwise you will have to avoid using
mapped images for this kind of pixel access pattern.

Mapping is done on the fly by default.  This means that for every pixel
access the row buffer pointer must be checked to see if it is valid before
an access is attempted.  If the row buffer pointer is invalid then i_remap
is called automatically before the pixel access:

	int i_remap(IMAGE *im, int row);

The integer returned by i_remap is a dummy value which should be ignored
(the dummy value is needed for the FAST macros with REMAP_ON_FLY).  The call
to i_remap maps the rows: (row-prelude) to (row-prelude+span-1) inclusive
(constrained to valid rows - see above where span and prelude are defined).

When using the image library in FAST mode (i.e. FAST is defined before
image.h is included in the source file), it is possible to use explicit
remapping and avoid the need to check the row buffer pointer for every pixel
access. To do this simply omit the definition of REMAP_ON_FLY in the source
file. This means that you must be sure rows are mapped before accessing
them. One easy way of doing this (only recommended for small images or
sparse access patterns) is to set the span to 0 so the entire image is
mapped and then call i_remap to map the entire image.  If you need explicit
remapping and cached mapping then you will need to call i_remap explicitly
every time you need to access a new span.  You should probably set the
prelude to 0 to make remapping more predicatable.  You must call i_remap
before the very first pixel access.

Related Functions

iget_mapping returns true (i.e. non-zero) if image is mapped.
iget_mapping_flags returns the current mapping mode (i.e. one of I_RDONLY, I_PRIVATE or I_RDWR).
iget_mapping_prelude get the current mapping prelude.
iget_mapping_span get the current mapping span.
imap map a raw format image file into virtual memory. The fname argument must supply the full path and filename. The flags argument must be one of I_RDONLY, I_PRIVATE or I_RDWR.
imapimg map a raw format image file into virtual memory. The fullname argument must supply the full path and filename. The flags argument must be one of I_RDONLY, I_PRIVATE or I_RDWR.
imapped_readonly returns true (i.e. non-zero) if image is mapped and mapped for read only access.
imapping turn mapping on and override the default mapping mode. The flags argument must be one of I_RDONLY, I_PRIVATE or I_RDWR.
ino_mapping turn mapping off.
iremap remap slice of mapped image to include specified row. Returns the number of times i_remap has been called for that image.
iset_mapping_prelude override the default mapping prelude.
iset_mapping_span override the default mapping span.
iunmap unmap a mapped image.

Other Topics

index | userguide | full | arithmetic | basic | binary | blocks | colour | compress | display | docs | fft | hist | image | io | makefile | masks | memory | misc | morph | pixel | rgb | stats | transform | error | mapping