From: Mark Shinwell <mshinwell@janestreet.com>
To: Bob Atkey <bob.atkey@gmail.com>
Cc: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] ANN: unboxed-arrays-0.1: Unboxed arrays for OCaml
Date: Mon, 20 Jan 2014 08:47:45 +0000 [thread overview]
Message-ID: <CAM3Ki762WFuxD5O50jvYDuJy_TcWrNKKX_wen4UncTqr9pa9fA@mail.gmail.com> (raw)
In-Reply-To: <CA+aevF8OTm2644EhnZ5pkr44yDXOSwJF1Y3OzuuHNJzEm6oSdg@mail.gmail.com>
On 19 January 2014 18:01, Bob Atkey <bob.atkey@gmail.com> wrote:
> The runtime representation of OCaml arrays usually stores the elements
> using a 'boxed' representation, meaning that if the value of a
> particular element cannot be stored within a single machine word
> (i.e., it is not an argument-less constructor or an `int` value), then
> the array actually contains a pointer to the representation of the
> element elsewhere in the heap. (Note that `float` arrays are special
> cased.) This boxing representation leads to an extra indirection when
> accessing elements of the array, means that memory is wasted, and
> decreases data locality, to the detriment of efficent cache usage.
Thanks for sharing your code. I also did an experiment
with this recently (although I would argue that it isn't always
clear that flat arrays are desirable). My flat array module
is designed to hold a sequence of values of record type. Pointers
to the records may be retrieved and then normal mutable field
updates may be used to change them. (In case you are wondering,
if you put some other variety of value in the array, then it's
probably safe but won't be useful---since in particular there
is no "set" method provided.)
module Flat_array : sig
type 'a t
val create : num_elements:int -> default:'a -> 'a t
val element_at : 'a t -> index:int -> 'a
end
Here's a simple example of its use. The code of the
implementation is left as an interesting exercise for the
reader ;)
type t = {
mutable foo : int;
mutable bar : string;
}
let default = { foo = 42; bar = "hello world"; }
let test () =
let arr = Flat_array.create ~num_elements:10 ~default in
let r = Flat_array.element_at arr ~index:4 in
Printf.printf "foo=%d, bar=%s\n%!" r.foo r.bar;
Gc.compact (); (* make sure we haven't corrupted the heap *)
r.foo <- 10;
r.bar <- "bar";
Gc.compact ();
Printf.printf "foo=%d, bar=%s\n%!" r.foo r.bar
--
module Flat_array : sig
type 'a t
val create : num_elements:int -> default:'a -> 'a t
val element_at : 'a t -> index:int -> 'a
end = struct
type _ t = Obj.t
let create ~num_elements ~default =
let fields_per_elt = Obj.size (Obj.repr default) in
let size = 1 + num_elements * (1 + fields_per_elt) - 1 in
let t = Obj.new_block Obj.closure_tag size in
let stride = Sys.word_size/8 * (fields_per_elt + 1) in
Obj.set_field t (size - 1) (Obj.repr stride);
let default = Obj.repr default in
for elt = 0 to num_elements - 1 do
let header_index_for_elt = (1 + fields_per_elt) * elt - 1 in
for field = 0 to fields_per_elt - 1 do
Obj.set_field t (header_index_for_elt + 1 + field)
(Obj.field default field)
done;
if elt > 0 then begin
let infix_header =
let infix_offset = elt * (fields_per_elt + 1) in
let actual_value =
(infix_offset lsl 10) lor Obj.infix_tag
in
assert (actual_value land 1 = 1);
actual_value lsr 1
in
Obj.set_field t header_index_for_elt (Obj.repr infix_header)
end
done;
t
let element_at t ~index =
let offset =
if index = 0 then 0
else
let t = ((Obj.magic t) : int array) in
let stride = t.(Array.length t - 1) in
stride * index
in
let record_is_at = Obj.add_offset t (Int32.of_int offset) in
Obj.obj record_is_at
end
next prev parent reply other threads:[~2014-01-20 8:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-19 18:01 Bob Atkey
2014-01-20 8:47 ` Mark Shinwell [this message]
2014-01-20 12:24 ` Bob Atkey
2014-01-20 12:33 ` Mark Shinwell
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=CAM3Ki762WFuxD5O50jvYDuJy_TcWrNKKX_wen4UncTqr9pa9fA@mail.gmail.com \
--to=mshinwell@janestreet.com \
--cc=bob.atkey@gmail.com \
--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