Version française
Home     About     Download     Resources     Contact us    
Browse thread
How to read different ints from a Bigarray?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Xavier Leroy <Xavier.Leroy@i...>
Subject: Re: [Caml-list] How to read different ints from a Bigarray?
Goswin von Brederlow wrote:

> I'm working on binding s for linux libaio library (asynchron IO) with
> a sharp eye on efficiency. That means no copying must be done on the
> data, which in turn means I can not use string as buffer type.
> 
> The best type for this seems to be a (int, int8_unsigned_elt,
> c_layout) Bigarray.Array1.t. So far so good.

That's a reasonable choice.

> Now I define helper functions:
> 
> let get_uint8 buf off = buf.{off}
> let set_uint8 buf off x = buf.{off} <- x
> 
> But I want more:
> 
> get/set_int8 - do I use Obj.magic to "convert" to int8_signed_elt?

Not at all.  If you ask OCaml's typechecker to infer the type of
get_uint8, you'll see that it returns a plain OCaml "int" (in the
0...255 range). Likewise, the "x" parameter to "set_uint8" has type
"int" (of which only the 8 low bits are used).

Repeat after me: "Obj.magic is not part of the OCaml language".

> And endian correcting access for larger ints:
> 
> get/set_big_uint16
> get/set_big_int16
> get/set_little_uint16
> get/set_little_int16
> get/set_big_uint24
> ...
> get/set_little_int56
> get/set_big_int64
> get/set_little_int64

The "56" functions look like a bit of overkill to me :-)

> What is the best way there? For uintXX I can get_uint8 each byte and
> shift and add them together. But that feels inefficient as each access
> will range check

Not necessarily.  OCaml 3.11 introduced unchecked accesses to
bigarrays, so you can range-check yourself once, then perform
unchecked accesses.  Use with caution...

> and the shifting generates a lot of code while cpus
> can usualy endian correct an int more elegantly.
> 
> Is it worth the overhead of calling a C function to write optimized
> stubs for this?

The only way to know is to benchmark both approaches :-(  My guess is
that for 16-bit accesses, you're better off with a pure Caml solution,
but for 64-bit accesses, a C function could be faster.

- Xavier Leroy