unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Imporved cons representatoin in guile
@ 2015-07-10 11:20 Stefan Israelsson Tampe
  2015-07-10 11:37 ` Stefan Israelsson Tampe
  2015-07-10 17:31 ` Stefan Monnier
  0 siblings, 2 replies; 4+ messages in thread
From: Stefan Israelsson Tampe @ 2015-07-10 11:20 UTC (permalink / raw)
  To: guile-devel

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

Hi,

I was complentating the cons cells in guile an was wondering if we could
pack our cons cells better than today. So this is some notes about this.

Currently if x is a cons cell we have the relation
x -> [SCMCAR,SCMCDR]

This is really neat and makes guiles conses quite compact e.g. a vector y
of two elements is
y -> [SCMTAG,SCMV1,SCMV2], where SCMTAG containes the datatype tag and
length of the
vector.

To compress even further we need a way to could use
x ->[SCM/2/SCM/2], witt SCM/2 the same tagging half the size as the normal
SCM with the interpretation that if
SCM/2 is a non emediate then it starts with 00 and is then interpreted as a
signed integer i and the real adress is x + i, e.g. a relative adress
regarding.

We of cause must also add a fat cons cell of the form
x -> [Tag,X,Y] for the case when SCM/2 is not fitting. Currently I can't
see this beeing common. But
if we later makes floating point represented via nan boxing e.g. stored
directly in a 64bit value then
the cons cell will be mostly fat and there would be a speed reduction using
cons cells. On the other hand there has been a considerable speed.

There is a final sematic case that needs to be fixed. if we do a setcar on
a thin cons cell and the cell
then becomes fat, we need to create the following

x -> oldthin -> newfat

e.g. we need to add a pointer type with the meaning of automatically follow
the pointer if we encounter it. then oldthin is also tagging a variant of a
cons cell. It is possible to keep it slim
in the code that all fat cons cells is represented like that.

How would a SCM_CAR be like?

SCM SCM_CAR(SCM x)
   if(THIN(x))
      {

      }

[-- Attachment #2: Type: text/html, Size: 2179 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Imporved cons representatoin in guile
  2015-07-10 11:20 Imporved cons representatoin in guile Stefan Israelsson Tampe
@ 2015-07-10 11:37 ` Stefan Israelsson Tampe
  2015-07-10 17:31 ` Stefan Monnier
  1 sibling, 0 replies; 4+ messages in thread
From: Stefan Israelsson Tampe @ 2015-07-10 11:37 UTC (permalink / raw)
  To: guile-devel

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

I managed to push the send button prematurey,

Here is the code i think that would be needed
SCM SCM_CAR(SCM x)
   SCM *pt = GET_REFERENCE(x)
   scm_t_bits val = SCM_UNPACK(*pt) & SCM/2; (Mask out the first half)
   if(1 & val == 0) //THIN
      {
          if(val & 6 == 0) //non emediate e.g. a pointer
            {
                int64 delta = promote_signed_ptr(val);
                return UNREF(pt + delta);
            }
          if(val & 2 == 1)   // integer
            {
                SCM_PACK(return promote_signed(val))
            }
           return SCM_PACK(val)
      }

     fat version of SCM comes here.

To note is that indeed we do get a more complex code here. But on the other
hand the extra logic is bit twiggelin and compiled using the cpu registers
only at most
a SCM_CAR will take twice the time. A SCM_CDR on the other hand need to
take in two SCM and is probably as fast or faster.

On Fri, Jul 10, 2015 at 1:20 PM, Stefan Israelsson Tampe <
stefan.itampe@gmail.com> wrote:

> Hi,
>
> I was complentating the cons cells in guile an was wondering if we could
> pack our cons cells better than today. So this is some notes about this.
>
> Currently if x is a cons cell we have the relation
> x -> [SCMCAR,SCMCDR]
>
> This is really neat and makes guiles conses quite compact e.g. a vector y
> of two elements is
> y -> [SCMTAG,SCMV1,SCMV2], where SCMTAG containes the datatype tag and
> length of the
> vector.
>
> To compress even further we need a way to could use
> x ->[SCM/2/SCM/2], witt SCM/2 the same tagging half the size as the normal
> SCM with the interpretation that if
> SCM/2 is a non emediate then it starts with 00 and is then interpreted as
> a signed integer i and the real adress is x + i, e.g. a relative adress
> regarding.
>
> We of cause must also add a fat cons cell of the form
> x -> [Tag,X,Y] for the case when SCM/2 is not fitting. Currently I can't
> see this beeing common. But
> if we later makes floating point represented via nan boxing e.g. stored
> directly in a 64bit value then
> the cons cell will be mostly fat and there would be a speed reduction
> using cons cells. On the other hand there has been a considerable speed.
>
> There is a final sematic case that needs to be fixed. if we do a setcar on
> a thin cons cell and the cell
> then becomes fat, we need to create the following
>
> x -> oldthin -> newfat
>
> e.g. we need to add a pointer type with the meaning of automatically
> follow the pointer if we encounter it. then oldthin is also tagging a
> variant of a cons cell. It is possible to keep it slim
> in the code that all fat cons cells is represented like that.
>
> How would a SCM_CAR be like?
>
> SCM SCM_CAR(SCM x)
>    if(THIN(x))
>       {
>
>       }
>
>
>
>
>
>
>

[-- Attachment #2: Type: text/html, Size: 4725 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Imporved cons representatoin in guile
  2015-07-10 11:20 Imporved cons representatoin in guile Stefan Israelsson Tampe
  2015-07-10 11:37 ` Stefan Israelsson Tampe
@ 2015-07-10 17:31 ` Stefan Monnier
  2015-07-14 13:18   ` Stefan Israelsson Tampe
  1 sibling, 1 reply; 4+ messages in thread
From: Stefan Monnier @ 2015-07-10 17:31 UTC (permalink / raw)
  To: guile-devel

> To compress even further we need a way to could use
> x ->[SCM/2/SCM/2], witt SCM/2 the same tagging half the size as the normal

Note that this is not specific to cons-cells.  I've been meaning to try
and experiment with such a box-compression scheme for several years, but
it never got high enough on the todo list (tho I did get a student to
look at it, but he gave up his MSc before getting far enough).

Note that because of set-car! and set-cdr! you need those SCM/2 fields
to be able to hold *any* value.  So an SCM/2 field can hold 3 different
things:
- an immediate value.
- a compressed reference, typically using relative addressing, where
  you'll want the GC to know about them, so it tries to keep/bring
  related objects near each other.
- a "proxy reference", which identifies a full SCM cell which contains
  the actual value.  It can be a relative pointer or an index in some
  table.

I imagined it working by dividing the heap into zones whose size
corresponds to the "reachability" of an SCM/2 relative pointer (so an
SCM/2 field can point to any other object within the same zone without
going through a proxy), and have each zone come with an array
of proxies.

I was thinking about this mostly in the context of 64bit boxes where the
SCM/2 references would basically only ever need to go through proxies once
the process size passes the 4GB limit.  But for small-memory systems
using 32bit pointers, the same idea might work as well.

Interestingly, this split into zones+proxies would also allow the GC to
operate on each zone independently (you don't need to trace the objects
in the other zones, only their proxies).


        Stefan




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Imporved cons representatoin in guile
  2015-07-10 17:31 ` Stefan Monnier
@ 2015-07-14 13:18   ` Stefan Israelsson Tampe
  0 siblings, 0 replies; 4+ messages in thread
From: Stefan Israelsson Tampe @ 2015-07-14 13:18 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: guile-devel

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

I think that getting cons cells to work with this is the easiest. With this
one can try to benchmark the change and investigate.

I think that I know enough of guile internals to make this work in a
branch. I can then post for anybody to try out. If it is a good idea to try
this let me know and I take a stab at it.

I think that getting this to work on more datastructures is a bit tricky.
One could for example use the current markings only on the proxied
datastructures but then one needs a huge commit to make it work.

Maybe you suggested this, But I think that the best would be to use two gc
memory regions one for the current mark system and one for the compressed
data structures where relative references is correctly followed. The
drawback with this is that we need to double the thread caches of lists of
free memory blocks. I know that this works cause I dabbled with multiple
memory types in guile-log when making the prolog variables gc-able. This
approach also enables an incremental development transitions of
datastructures suitable for compression.

> you'll want the GC to know about them, so it tries to keep/bring
> related objects near each other.

does bdw-gc do this on current cons cells?

> I imagined it working by dividing the heap into zones whose size
> corresponds to the "reachability" of an SCM/2 relative pointer (so an
> SCM/2 field can point to any other object within the same zone without
> going through a proxy), and have each zone come with an array
> of proxies.

To make this work in a good way is quite difficult. You need bdw-gc to
group the free memory in relation to ther allocation block in order to
simulate the demon of Maxwell if this is not currently done you need quite
a hack into the bdw-gc code to make it work.

Especially constants are loaded via installing pages and here I suspect
that we can get problems with a lot of references going out of bounds. When
it comes with the heap memory from the gc would that not mostly be within
30 bit relative adresses? anyhow I agree for large programs of aroung 1GB
we would start to see more and more proxied datastructures ending with
somthing that is unoptimal. I imagined that any solution to guile that
incorporated a compresion feature would need the possibility via a
configuration option to use the old uncompressed system. Especially it
would be questionable to have large datastructures like vectors to be
compressed cause the although small but positive probability of referencing
constants.


>I was thinking about this mostly in the context of 64bit boxes where the
>SCM/2 references would basically only ever need to go through proxies once
>the process size passes the 4GB limit.  But for small-memory systems
>using 32bit pointers, the same idea might work as well.

Yeah, the information slack is quite high on these Boxes we need to make
sure not to force this feature on the 32bit ones.

> Interestingly, this split into zones+proxies would also allow the GC to
> operate on each zone independently (you don't need to trace the objects
> in the other zones, only their proxies).

Not sure I follow, but marking a proxy implies marking in the other zone so
I can't see this atm.

What is not too difficult is to be able to have say 10 memory regions and
then when you work with scheme code of large applications you could do,

(with-mem-region 8 thunk)

With the meaning that all allocation comes from region 8. This is a
complexity code wise, but could be something that can be profiled out and
just used on the hot code paths and datastructures. Now I'm not sure how
well bdw-gc handles this but I think that controlling the adress ranges of
allocated blocks is a relative small change to the code base, the issue
here is probably portability.

Ok That's all for now,
Cheers!



On Fri, Jul 10, 2015 at 7:31 PM, Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

> > To compress even further we need a way to could use
> > x ->[SCM/2/SCM/2], witt SCM/2 the same tagging half the size as the
> normal
>
> Note that this is not specific to cons-cells.  I've been meaning to try
> and experiment with such a box-compression scheme for several years, but
> it never got high enough on the todo list (tho I did get a student to
> look at it, but he gave up his MSc before getting far enough).
>
> Note that because of set-car! and set-cdr! you need those SCM/2 fields
> to be able to hold *any* value.  So an SCM/2 field can hold 3 different
> things:
> - an immediate value.
> - a compressed reference, typically using relative addressing, where
>   you'll want the GC to know about them, so it tries to keep/bring
>   related objects near each other.
> - a "proxy reference", which identifies a full SCM cell which contains
>   the actual value.  It can be a relative pointer or an index in some
>   table.
>
> I imagined it working by dividing the heap into zones whose size
> corresponds to the "reachability" of an SCM/2 relative pointer (so an
> SCM/2 field can point to any other object within the same zone without
> going through a proxy), and have each zone come with an array
> of proxies.
>
> I was thinking about this mostly in the context of 64bit boxes where the
> SCM/2 references would basically only ever need to go through proxies once
> the process size passes the 4GB limit.  But for small-memory systems
> using 32bit pointers, the same idea might work as well.
>
> Interestingly, this split into zones+proxies would also allow the GC to
> operate on each zone independently (you don't need to trace the objects
> in the other zones, only their proxies).
>
>
>         Stefan
>
>
>

[-- Attachment #2: Type: text/html, Size: 9002 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-07-14 13:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-10 11:20 Imporved cons representatoin in guile Stefan Israelsson Tampe
2015-07-10 11:37 ` Stefan Israelsson Tampe
2015-07-10 17:31 ` Stefan Monnier
2015-07-14 13:18   ` Stefan Israelsson Tampe

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 read-only IMAP folder(s) and NNTP newsgroup(s).