Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
[Caml-list] BigArray extensions
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2004-08-03 (11:49)
From: David McClain <dmcclain1@m...>
Subject: [Caml-list] BigArray extensions
After close examination of the BigArray library code, I see that you are
already paying the price of discriminating between C and Fortran modes.
Adding Scientist mode requires only one more bit in the flags. The required
code change from Accountant mode to Scientist mode is simply to elide the
bounds checking and compute an effective offset for any one index given as

eff_index = index[i] % b->dim[i];
if(eff_index < 0)
  eff_index += b->dim[i];

then in computing the total offset for this index,

offset = offset * b->dim[i] + eff_index;

Fortran mode is similarly accommodated by decrementing the index[i] value by
1 before computing the modulo.

Accommodating windowed file mapping requires a slight extension of a proxy
object which can remain transparent to most of the rest of the code. What
does change are the mass copying and filling operations, serialization, and
of course the need to ensure that the memory in question is currently mapped
into memory. That last operation can occur in a simple check at the tail end
of bigarray_offset. But mass copying and filling must take care to work in
chunks limited by the remaining mapped memory in the current mapping, then
remapping additional chunks as needed.

Since the memmapped files are slower than normal memory operations anyway,
yet hundreds of times faster than fread and fwrite access, this extra cost
is still worthwhile as long as we discriminate between normal memory arrays
and memmapped arrays at the outset and don't force every single access of
both kinds to go through the map checking code.

As for memory alignment issues, you have those whether you use memmaped
files or simple buffered I/O. The moment you read any portion of a file into
a buffer you have potential alignment issues. You then have to rely on the
underlying file representation to respect alignment requirements, which most
modern file formats already do. There is still the issue of endianness,
which is generally already accommodated using XDR standard representation.
Again, this is only an issue for memmapped files and the endianness could be
accommodated with yet another flag and another subtype in the declaration of
the mapping.

I also added some quick checks in bigarray_compare to escape quickly on
identity, and when two bigarrays match in dimensions and have the same
underlying data address.

These are all trivial changes to the library code.

The question is, if I make these changes, will I get the same performance
improvements from the %labeled external declarations in the OCaml modules?
And if so, just what performance improvement is made possible in this case
with such labeling?

I have examined the compiler code generation, but I am not yet able to tell
whether or not the compiler makes a call to the C glue code in any event, or
whether it performs some in-line get-set expansion. If it does the inline
get-set, then obviously this won't work for mmapped files. But if it just
performs a quick call to the C glue, then it will.

Given that the code must work already for either C or Fortran modes, it
seems too much to expect that the compiler will inline any memory accessing,
but instead will just perform some kind of "quick" call to the C glue layer.

There is a distinct difference between mmapped arrays and normal BigArrays.
While a memory bound BigArray can have subarrays and slices placed on it,
akin to Lisp displaced arrays, a memory bound normal BigArray cannot validly
mutate the underlying data representation. However, a memmapped file can and
must permit mutated declarations of the element types, since a file is
typically heterogeneous in content.

Handling multiple arrays into the memmapped array is easily accomplished
within the existing code by first permitting this mutation and secondly by
using the proxy mappings already in place.

Using memmapped access implies the use of kernel provided resources that are
relatively scarce. Leaving it to the finalization code to unmap these files
when no longer used might imply a situation of exhausted resources even
though none are currently in use, simply because it takes too long for the
GC to reap the dead objects for finalization.

Finally, it appears that the bulk of the data array area, the so-called
Arena, is allocated with malloc in the external heap. Hence it should be
safe to make a call to a routine called arena() which on normal OCaml double
arrays is identity, and on BigArrays it simply returns the data pointer.
This allows uniform access to both kinds of arrays from trusted (i.e.,
not-bounds checked) code using declared unsafe-access methods.

David McClain
Senior Corporate Scientist
Avisere, Inc.

+1.520.390.7738 (USA)

To unsubscribe, mail Archives:
Bug reports: FAQ:
Beginner's list: