From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 2496D7EC6E for ; Mon, 27 Jan 2014 17:18:45 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of yotambarnoy@gmail.com) identity=pra; client-ip=209.85.216.178; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yotambarnoy@gmail.com"; x-sender="yotambarnoy@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of yotambarnoy@gmail.com designates 209.85.216.178 as permitted sender) identity=mailfrom; client-ip=209.85.216.178; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yotambarnoy@gmail.com"; x-sender="yotambarnoy@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-qc0-f178.google.com) identity=helo; client-ip=209.85.216.178; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yotambarnoy@gmail.com"; x-sender="postmaster@mail-qc0-f178.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjMDAE2G5lLRVdiylGdsb2JhbABZg0RWqRyKaYhUgQ0IFg4BAQEBBwsLCRIqgiUBAQEDAScZARsSCwEDDAYFCxohIgERAQUBChIGJYdeAQMJCA2eEIxcgwmSZAoZJwMKZIRyEQEFDI4pVAQHhDgEiUiOX4Eyjn8YKYR3HoEs X-IPAS-Result: AjMDAE2G5lLRVdiylGdsb2JhbABZg0RWqRyKaYhUgQ0IFg4BAQEBBwsLCRIqgiUBAQEDAScZARsSCwEDDAYFCxohIgERAQUBChIGJYdeAQMJCA2eEIxcgwmSZAoZJwMKZIRyEQEFDI4pVAQHhDgEiUiOX4Eyjn8YKYR3HoEs X-IronPort-AV: E=Sophos;i="4.95,729,1384297200"; d="scan'208";a="46301114" Received: from mail-qc0-f178.google.com ([209.85.216.178]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 27 Jan 2014 17:18:44 +0100 Received: by mail-qc0-f178.google.com with SMTP id m20so8199576qcx.23 for ; Mon, 27 Jan 2014 08:18:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=E36NMuk7GQDT8oPmJ5fxCt3bNrimS1jMa//A2u7O9O4=; b=Uq8Ma4ti3wt7NP1UqD09OYL4ZqYzi7rS52bAp3ezyGvcJYICCUsZcdH0QxJSl2je/i 3o7xUBlz8kn6Kv+sshsDn3wyFN6xeaFz8tcbiaWqdg5zFhESGoVXnjVGfMz61EieELcZ BrRV5Z7FVfyIcrqXFssNah6NysVFmlH3Wtz/6/exiH/TANdNRjLHUFiyus3lYxedYaXy roSKWnOd/gakCFr65u7PIGGCzTQzI9JAEQU7tVrNv/SvAywEo893vrUTmGDIuLknYPGG 1nMExOULguHEug4MhSJygiyOSyqC07LOyX+npkuB3abVWqWi0WrsXfuE3YnxM67Lgjic cFGQ== X-Received: by 10.224.79.133 with SMTP id p5mr41750140qak.56.1390839523108; Mon, 27 Jan 2014 08:18:43 -0800 (PST) MIME-Version: 1.0 Received: by 10.224.95.8 with HTTP; Mon, 27 Jan 2014 08:18:23 -0800 (PST) In-Reply-To: <20140127152944.GA29326@frosties> References: <20140120101654.GI26447@frosties> <08bc01cf17b8$9263d070$b72b7150$@ffconsultancy.com> <20140123092925.GB20624@frosties> <01c401cf1891$b1fb1360$15f13a20$@ffconsultancy.com> <026101cf18dd$756c13d0$60443b70$@ffconsultancy.com> <030501cf1925$45380fa0$cfa82ee0$@ffconsultancy.com> <20140127152944.GA29326@frosties> From: Yotam Barnoy Date: Mon, 27 Jan 2014 11:18:23 -0500 Message-ID: To: Goswin von Brederlow Cc: Ocaml Mailing List Content-Type: multipart/alternative; boundary=047d7bf0de7ab6ec6704f0f60fb5 Subject: Re: [Caml-list] How much optimized is the 'a option type ? --047d7bf0de7ab6ec6704f0f60fb5 Content-Type: text/plain; charset=ISO-8859-1 > > But you can't just put a float 42.0 on the heap or even stack when the > GC might get called. That needs to be boxed in some way to avoid it > getting misread as pointer. > > It wouldn't be too hard to add a word of metadata to the stack to tell the GC what's a pointer and what isn't. Haskell does this for function calls (in fact, if the metadata doesn't fit in a word, it allocates a separate metadata structure), and F# has this from the .NET runtime which has full type metadata for everything. Problem is that a value is a fixed size and fits in a register. A > tuple does not. (int * float) even takes the space of 3 values on > 32bit. You can unbox that in the optimizer for local use but in memory > and in function calls you need to pass this as box. Otherwise > polymorphic functions break. > > Putting larger structures into an array without boxing also only works > for immutable objects and by copying them every time they are passed > around. You can't copy a mutable and you can't pass a pointer to the > middle of an array to another function or the GC might freak out. > Leaving it to the optimizer is problematic because it might cause a lot of unneeded boxing and unboxing. Haskell has the {- #UNPACK -} pragma to unbox types. You have to be really careful in haskell with this, because you're also changing the evaluation semantics to be strict. This makes for really ugly optimized haskell code, but maybe we can do something similar (but not as ugly). F# inherits .NET's struct types, which are similarly limited, but also useful. Of course, once you unbox, all parametric polymorphism is lost, but because you have control over it, you can decide where it's worthwhile. An example of unpack usage in haskell: data T = T {-# UNPACK #-} !(Int,Int) which would be equivalent to something like type t = (int * int) [@u] Note that the whole tuple is unboxed. In haskell, you can now do f :: T -> Int f (T(i1,i2)) = i1 + i2 and in ocaml you'd do let f : t -> int = fun (i1,i2) = i1 + i2 Of course, this would require more metadata for the stack. For the heap, you'd probably want to just use a new tag or the custom tag. For ocaml you'd also probably have to stipulate that polymorphic marshalling cannot be performed on this type, and neither can polymorphic comparison -- you'd have to have specific marshalling/comparison functions, which aren't too difficult to generate automatically. -Yotam > > -- > 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 > --047d7bf0de7ab6ec6704f0f60fb5 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
But you can't just put a float 42.0 on the heap or even stack when the<= br> GC might get called. That needs to be boxed in some way to avoid it
getting misread as pointer.


It wouldn'= t be too hard to add a word of metadata to the stack to tell the GC what= 9;s a pointer and what isn't. Haskell does this for function calls (in = fact, if the metadata doesn't fit in a word, it allocates a separate me= tadata structure), and F# has this from the .NET runtime which has full typ= e metadata for everything.

Problem is that a val= ue is a fixed size and fits in a register. A
tuple does not. (int * float) even takes the space of 3 values on
32bit. You can unbox that in the optimizer for local use but in memory
and in function calls you need to pass this as box. Otherwise
polymorphic functions break.

Putting larger structures into an array without boxing also only works
for immutable objects and by copying them every time they are passed
around. You can't copy a mutable and you can't pass a pointer to th= e
middle of an array to another function or the GC might freak out.

Leaving it to the optimizer is problematic because it= might cause a lot of unneeded boxing and unboxing.
Haskell has the {- #= UNPACK -} pragma to unbox types. You have to be really careful in haskell w= ith this, because you're also changing the evaluation semantics to be s= trict. This makes for really ugly optimized haskell code, but maybe we can = do something similar (but not as ugly). F# inherits .NET's struct types= , which are similarly limited, but also useful. Of course, once you unbox, = all parametric polymorphism is lost, but because you have control over it, = you can decide where it's worthwhile.

An example of unpack usage in haskell:
da=
ta T =3D T {-# UNPACK #-} !(Int,Int)
which would be equivalent to some= thing like
type t =3D (int * int) [@u]

Note that the whole tuple is unboxed.

In haskell, yo= u can now do
f :: T -> Int
f (T(i1,i2)) =3D i1 + i2
and in ocaml you'd do

l= et f : t -> int =3D fun (i1,i2) =3D i1 + i2

Of course, this would require more metadata for the stack. For the heap, y= ou'd probably want to just use a new tag or the custom tag. For ocaml y= ou'd also probably have to stipulate that polymorphic marshalling canno= t be performed on this type, and neither can polymorphic comparison -- you&= #39;d have to have specific marshalling/comparison functions, which aren= 9;t too difficult to generate automatically.

-Yotam

=A0

--
Caml-list mailing list. =A0Subscription management and archives:
ht= tps://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

--047d7bf0de7ab6ec6704f0f60fb5--