caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Guillaume Yziquel <guillaume.yziquel@citycable.ch>
To: Nicolas Ojeda Bar <nojb@math.harvard.edu>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] obj magic performance and other questions
Date: Wed, 16 Mar 2011 03:21:50 +0100	[thread overview]
Message-ID: <20110316022150.GJ22969@localhost> (raw)
In-Reply-To: <057400AC-9E39-45CC-AB7A-35C67C339F83@math.harvard.edu>

Le Tuesday 15 Mar 2011 à 12:05:31 (-0400), Nicolas Ojeda Bar a écrit :
> Hello,
> 
> This is not very efficient. I can use Obj.magic to access that same field as
> follows:
> 
> let rec2_b x =
> Obj.obj (Obj.field (Obj.field (Obj.repr x.children 0) 0))

Seems that you messed up some parentheses.

> My question is: is this use of Obj safe? and is this compiled to (two) simple
> array accesses? Or is Obj.obj doing something behind the scenes?

yziquel@seldon:~/sandbox/ocaml$ cat a.ml 
let f x = Obj.obj (Obj.field (Obj.field (Obj.repr x) 0) 0)
yziquel@seldon:~/sandbox/ocaml$ ocamlopt -c -S -dlambda a.ml 
(seq
  (let
    (f/1030
       (function x/1031
         (id (array.unsafe_get (array.unsafe_get (id x/1031) 0) 0))))
    (setfield_imm 0 (global A!) f/1030))
  0a)

So it should be compiled to array accesses. However, they are not so
simple array accesses due to OCaml data layout. Moreover, there's this
'id' around. Let's see:

yziquel@seldon:~/sandbox/ocaml$ cat a.s

[...]

camlA__f_1030:
	subq	$8, %rsp
.L103:
	movq	%rax, %rdi
	movzbq	-8(%rdi), %rax

So the stack has been managed, and the %rax registers now contains the
tag of the 'x' argument to 'f'.

	cmpq	$254, %rax

This checks that the tag is or isn't the tag of an array of doubles.
(Obj.double_array_tag is 254). So we shouldn't jump on the ext 'je'.

	je	.L102
	movq	(%rdi), %rbx

The register %rbx now contains the first field of 'x'.

	jmp	.L101

[...]

.L101:
	movzbq	-8(%rbx), %rax

This looks at the tag of the first field of 'x', and checks below if it
is an array of doubles.

	cmpq	$254, %rax
	je	.L100
	movq	(%rbx), %rax

%rax now contains the first field of the first field of 'x'.

	addq	$8, %rsp
	ret

And 'f' returns with what you want.

So, aside from checking if tag is 254, it's essentially two direct array
accesses, and the 'id' function of Obj.repr and Obj.obj is erased.

	external repr : 'a -> t = "%identity"
	external obj : t -> 'a = "%identity"
	external field : t -> int -> t = "%obj_field"

You could probably hack the compiler to avoid the tag checking if you
really wanted to avoid the 254 test. That'd require another "%..." to be
implemented I guess.

> Thanks!
> N

-- 
     Guillaume Yziquel


  parent reply	other threads:[~2011-03-16  2:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-15 16:05 Nicolas Ojeda Bar
2011-03-15 17:17 ` Dario Teixeira
2011-03-16  2:21 ` Guillaume Yziquel [this message]
     [not found] ` <325023989.96091.1300242147328.JavaMail.root@zmbs4.inria.fr>
2011-03-16  8:46   ` Fabrice Le Fessant
2011-03-17 16:36 ` Damien Doligez

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=20110316022150.GJ22969@localhost \
    --to=guillaume.yziquel@citycable.ch \
    --cc=caml-list@yquem.inria.fr \
    --cc=nojb@math.harvard.edu \
    /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;
as well as URLs for NNTP newsgroup(s).