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.
| 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. |
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