From: Goswin von Brederlow <goswin-v-b@web.de>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Re: How to read different ints from a Bigarray?
Date: Wed, 28 Oct 2009 16:00:46 +0100 [thread overview]
Message-ID: <87639zd0m9.fsf@frosties.localdomain> (raw)
In-Reply-To: <slrnhegkik.q9j.sylvain@gallu.homelinux.org> (Sylvain Le Gall's message of "Wed, 28 Oct 2009 14:16:52 +0000 (UTC)")
Sylvain Le Gall <sylvain@le-gall.net> writes:
> Hello,
>
> On 28-10-2009, Goswin von Brederlow <goswin-v-b@web.de> wrote:
>> Hi,
>>
>> 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.
>>
>> 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?
>>
>> 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
>>
>> 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 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?
>>
>> And last:
>>
>> get/set_string, blit_from/to_string
>>
>> Do I create a string where needed and then loop over every char
>> calling s.(i) <- char_of_int buf.{off+i}? Or better a C function using
>> memcpy?
>>
>> What do you think?
>>
>
> Well, we talk about this a little bit, but here is my opinion:
> - calling a C function to add a single int will generate a big overhead
> - OCaml string are quite fast to modify values
>
> So to my mind the best option is to have a buffer string (say 16/32
> char) where you put data inside and flush it in a single C call to
> Bigarray.
>
> E.g.:
> let append_char t c =
> if t.idx >= 64 then
> (
> flush t.bigarray t.buffer;
> t.idx <- 0
> );
> t.buffer.(t.idx) <- c;
> t.idx <- t.idx + 1
>
> let append_little_uint16 t i =
> append_char t ((i lsr 8) land 0xFF);
> append_char t ((i lsr 0) land 0xFF)
>
>
> I have used this kind of technique and it seems as fast as C, and a lot
> less C coding.
>
> Regards,
> Sylvain Le Gall
This wont work so nicely:
- Writes are not always in sequence. I want to do a stream access
too where this could be verry effective. But the plain buffer is
more for random / known offset access. At a minimum you would have
holes for alignment.
- It makes read/write buffers complicated as you need to flush or peek
the string in case of uncommited changes. I can't do write-only
buffers as I want to be able to write a buffer and then add a
checksum to it in my application. The lib should not block that.
- The data is passed to libaio and needs to be kept alive and unmoved
as long as libaio knows it. I was hoping I could use the pointer to
the data to register/unregister GC roots without having to add a
another custom header and indirections.
I also still wonder how bad a C function call really is. Consider the
case of writing an int64.
Directly: You get one C call that does range check, endian convert and
write in one go.
Bffered: With your code you have 7 Int64 shifts, 8 Int64 lands, 8
conversions to int, at least one index check (more likely 8 to avoid
handling unaligned access) and 1/8 C call to blit the 64 byte buffer
string into the Bigarray.
MfG
Goswin
PS: Is a.{i} <- x a C call?
next prev parent reply other threads:[~2009-10-28 15:00 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-28 13:54 Goswin von Brederlow
2009-10-28 14:16 ` Sylvain Le Gall
2009-10-28 15:00 ` Goswin von Brederlow [this message]
2009-10-28 15:17 ` Sylvain Le Gall
2009-10-28 17:57 ` [Caml-list] " Goswin von Brederlow
2009-10-28 18:19 ` Sylvain Le Gall
2009-10-28 21:05 ` [Caml-list] " Goswin von Brederlow
2009-10-28 21:26 ` Sylvain Le Gall
2009-10-28 22:48 ` [Caml-list] " blue storm
2009-10-29 9:50 ` Goswin von Brederlow
2009-10-29 10:34 ` Goswin von Brederlow
2009-10-29 12:20 ` Richard Jones
2009-10-29 17:07 ` Goswin von Brederlow
2009-10-30 20:30 ` Richard Jones
2009-11-01 15:11 ` Goswin von Brederlow
2009-11-01 19:57 ` Richard Jones
2009-11-02 16:11 ` Goswin von Brederlow
2009-11-02 16:33 ` Mauricio Fernandez
2009-11-02 20:27 ` Richard Jones
2009-11-03 13:18 ` Goswin von Brederlow
2009-11-02 20:48 ` Goswin von Brederlow
2009-10-29 20:40 ` Florian Weimer
2009-10-29 21:04 ` Gerd Stolpmann
2009-10-29 23:43 ` Goswin von Brederlow
2009-10-30 0:48 ` Gerd Stolpmann
2009-10-29 23:38 ` Goswin von Brederlow
2009-10-28 15:37 ` [Caml-list] " Olivier Andrieu
2009-10-28 16:05 ` Sylvain Le Gall
2009-10-28 15:43 ` [Caml-list] " Gerd Stolpmann
2009-10-28 16:06 ` Sylvain Le Gall
2009-10-28 18:09 ` [Caml-list] " Goswin von Brederlow
2009-10-28 17:09 ` Xavier Leroy
2009-10-28 19:05 ` Goswin von Brederlow
2009-10-29 17:05 ` Goswin von Brederlow
2009-10-29 18:42 ` Christophe TROESTLER
2009-10-29 19:03 ` Goswin von Brederlow
2009-10-29 18:48 ` Sylvain Le Gall
2009-10-29 23:25 ` [Caml-list] " Goswin von Brederlow
2009-11-03 17:16 Charles Forsyth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87639zd0m9.fsf@frosties.localdomain \
--to=goswin-v-b@web.de \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox