caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Fabrice Le Fessant <Fabrice.Le_fessant@inria.fr>
To: caml-list@inria.fr
Subject: Re: [Caml-list] obj magic performance and other questions
Date: Wed, 16 Mar 2011 09:46:55 +0100	[thread overview]
Message-ID: <4D8078FF.2050503@inria.fr> (raw)
In-Reply-To: <325023989.96091.1300242147328.JavaMail.root@zmbs4.inria.fr>

[-- Attachment #1: Type: text/plain, Size: 2943 bytes --]

Well, actually, pattern matching is compiled to optimize access to
fields depending on their types, so the version without Obj is probably
actually faster than the version with Obj.

Also, the test with 254 should probably not be removed, as records can
also be represented using double arrays (actually, your record rec3 will
be represented as a double_array). That's the reason why using Obj to
optimize code is often not a very good idea, as you lose the type
information, and type information is important for faster access to data
structures.

--Fabrice

On 03/16/2011 03:22 AM, Guillaume Yziquel wrote:
> 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
> 

[-- Attachment #2: fabrice_le_fessant.vcf --]
[-- Type: text/x-vcard, Size: 384 bytes --]

begin:vcard
fn:Fabrice LE FESSANT
n:LE FESSANT;Fabrice
org:INRIA Saclay -- Ile-de-France;Projet OCamlPro
adr;quoted-printable:;;Parc Orsay Universit=C3=A9 ;Orsay CEDEX;;91893;France
email;internet:fabrice.le_fessant@inria.fr
title;quoted-printable:Charg=C3=A9 de Recherche
tel;work:+33 1 74 85 42 14
tel;fax:+33 1 74 85 42 49 
url:http://fabrice.lefessant.net/
version:2.1
end:vcard


  parent reply	other threads:[~2011-03-16  8:52 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
     [not found] ` <325023989.96091.1300242147328.JavaMail.root@zmbs4.inria.fr>
2011-03-16  8:46   ` Fabrice Le Fessant [this message]
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=4D8078FF.2050503@inria.fr \
    --to=fabrice.le_fessant@inria.fr \
    --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;
as well as URLs for NNTP newsgroup(s).