caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Gabriel Scherer <gabriel.scherer@gmail.com>
To: Pierre Chambart <pierre.chambart@ocamlpro.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] The verdict on "%identity"
Date: Tue, 20 Nov 2012 17:19:34 +0100	[thread overview]
Message-ID: <CAPFanBFUkri75W2vFqS5dNN4BUWw7W7-CPQ9HnwwdCEwtqjtYw@mail.gmail.com> (raw)
In-Reply-To: <20121120112519.2e155a09@crans.org>

This is good advice in general, and using ocamlobjinfo to get inlining
information from the .cmx is indeed a very good idea.

Regarding -dcmm vs. -S, I generally use -dcmm myself (much more
readable), but it is not the right tool in this case. The cmm produced
for my test.ml code does make a difference between the three styles:
     (let testA/1046 (let x/1075 "camlTest__3" x/1075)
       (store (+a "camlTest" 20) testA/1046))
     (let testB/1047 (let prim/1076 "camlTest__2" prim/1076)
       (store (+a "camlTest" 24) testB/1047))
     (let testD/1048 "camlTest__1"
        (store (+a "camlTest" 28) testD/1048))

In fact, the removal of the trivial (let x = foo in x) does not happen
during the inlining passes in closure.ml, but much later at the
register allocation phase, where there is indeed a strong preference
for eg. testA/1046 and x/1705 to be given the same register, and the
useless move is erased. I make no claim of how robust this behavior
will be in a different case (eg. with higher register pressure), but
I'm not sure I really care.
I'd rather have people study the behavior on the compiler the real
performance-critical applications and suggest potential style changes
in the program (or optimization changes in the compiler) in cases
where this really make a performance difference. Writing code in a
certain way because "the generated code is nicer" is usually not worth
the trouble.

On Tue, Nov 20, 2012 at 11:25 AM, Pierre Chambart
<pierre.chambart@ocamlpro.com> wrote:
> To know what will be generated after inlining I prefer to use -dcmm,
> which is closer to the original code than the assembly and still show
> show inlining result (and if you are using the svn trunk, you can use
> -dclambda which show a higher level code, without allocations and
> boxing).
>
> Inlining of OCaml functions works the same way inside a module or
> cross-module. It looks at the function size and if it smaller than
> a certain threshold, it will be inlined. To know if it will happen to
> your function, look at the result of ocamlobjinfo.
>
> for instance:
> module.mli:
>
> type t
> external id_prim : string -> t = "%identity"
> val id : string -> t
> val f : int -> int
> val g : int -> int
>
> module.ml:
>
> type t = string
> external id_prim : 'a -> 'a = "%identity"
> let id x = x
> let f x = x + x + x + x
> let g x = x + x + x + x + x + x + x + x
>
> ocamlobjinfo module.cmx:
>
> ...
> Approximation:
>   (0: function camlIdentity__id_1010 arity 1 (closed) (inline) ->  _;
>    1: function camlIdentity__f_1012 arity 1 (closed) (inline) ->  _;
>    2: function camlIdentity__g_1014 arity 1 (closed) ->  _)
> ...
>
> the function id and f will be inlined whatever the context of the call
> is, but g won't be.
>
> If you want a function to be inlined, you can use the -inline option of
> ocamlopt to increase the maximum size of inlined functions in the
> module. Notice that recursive functions can't be inlined.
>
> The usage of private type is different.
> When using generic comparison/equality/hash/set in an array, the
> compiler generate an optimised code when the type is known to be one of
> the fast cases:
>
> module M1 : sig
>   type t = private int
> end = struct type t = int end
> module M2 : sig
>   type t
> end = struct type t = int end
>
> let a x y = x > y
> let b (x:int) y = x > y
> let c (x:M1.t) y = x > y
> let d (x:M2.t) y = x > y
>
> the result of ocamlopt -dcmm:
>
> (function camlCompare__a_1014 (x/1015: addr y/1016: addr)
>  (extcall "caml_greaterthan" x/1015 y/1016 addr))
>
> (function camlCompare__b_1017 (x/1018: addr y/1019: addr)
>  (+ (<< (> x/1018 y/1019) 1) 1))
>
> (function camlCompare__c_1020 (x/1021: addr y/1022: addr)
>  (+ (<< (> x/1021 y/1022) 1) 1))
>
> (function camlCompare__d_1023 (x/1024: addr y/1025: addr)
>  (extcall "caml_greaterthan" x/1024 y/1025 addr))
>
> Here b and c will be a lot faster than a and d.
> Using private type allows to keep those informations acros modules.
> --
> Pierre
>
> Le Mon, 19 Nov 2012 18:28:32 +0000,
> David House <dhouse@janestreet.com> wrote :
>
>> If you wanted to investigate this yourself, you could compile with -S
>> and look at the generated assembly. For such short functions, this is
>> generally not very hard.
>>
>> On Mon, Nov 19, 2012 at 6:18 PM, Dario Teixeira
>> <darioteixeira@yahoo.com> wrote:
>> > Hi,
>> >
>> >> Wouldn't 'type t = private string' help the compiler optimize this?
>> >
>> >
>> > Possibly, though the semantics would change: what before was
>> > an abstract type is now translucent (ie, not quite transparent).
>> >
>> > Regards,
>> > Dario
>> >
>> > --
>> > Caml-list mailing list.  Subscription management and archives:
>> > https://sympa.inria.fr/sympa/arc/caml-list
>> > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> > Bug reports: http://caml.inria.fr/bin/caml-bugs
>>
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

  reply	other threads:[~2012-11-20 16:20 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-19 17:49 Dario Teixeira
2012-11-19 18:02 ` Török Edwin
2012-11-19 18:18   ` Dario Teixeira
2012-11-19 18:28     ` David House
2012-11-20  9:53       ` Gabriel Scherer
2012-11-20 10:25       ` Pierre Chambart
2012-11-20 16:19         ` Gabriel Scherer [this message]
2012-11-20 19:03           ` Vincent HUGOT
2012-11-20 20:43           ` Dario Teixeira

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=CAPFanBFUkri75W2vFqS5dNN4BUWw7W7-CPQ9HnwwdCEwtqjtYw@mail.gmail.com \
    --to=gabriel.scherer@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=pierre.chambart@ocamlpro.com \
    /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).