Hi,
If you read the squeak vm mailing they talk about read only objects. But wait, we've read only why should we change it?? In GST it's done by testing at "each" access if the object is RO or not. But we can do it lazily by using the hardware and operating system. Objects can be putted in a separate space with read-only access, thus we get a page fault when you try to change an object. I've implemented the first step a separate space for the *old* read-only objects. I've first fixed a bug with the oldspace_nomemory each space should have its own function. Thus there are for each space a *space_nomemory, gst_init_mem_default initialize the new ro_oldspace. The macro MAKE_OOP_READONLY calls the _gst_make_oop_readonly function: * first I check if the oop ro state is the same as the new state; if yes I leave. * If the object is fixed or young I only change the state BUT if the object is old it is moved inside a ro_oldspace if it becomes RO or it's moved from the ro_oldspace to the oldspace it is writeable * gst_make_oop_fixed check if is old and remove the object from the right space (oldspace or ro_old_space) * the oldspace_nomemory, fixedspace_nomemory, ro_oldspace_nomemory returns the correct heap ;-) * _gst_compact: i'll compact the memory of both oldspace and ro_oldspace, I don't use the new heap size to grow the ro_oldspace heap size. * _gst_sweep_oop is changed to free the memory from the right space ;-) * the image loading is updated to take care of the ro_oldspace I think it's all ;-) Right now the ro mapping is not done but as Paolo said on IRC the patch will give less false positive on grey page scanning. Cheers, Gwen _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk ro-space.patch (13K) Download Attachment |
On 05/12/2011 05:16 PM, Gwenael Casaccio wrote:
> Hi, > > If you read the squeak vm mailing they talk about read only objects. > But wait, we've read only why should we change it?? In GST it's done by > testing at "each" access if the object is RO or not. But we can do it lazily > by using the hardware and operating system. Objects can be putted in a > separate space with read-only access, thus we get a page fault when you try to > change an object. > > How many read-only objects do we have in a bootstrapped image? In a typical iliad application? Does it make sense to optimize for it? or will RO handling just become more easy and this is a cleanup? _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/12/2011 05:24 PM, Holger Hans Peter Freyther wrote:
> How many read-only objects do we have in a bootstrapped image? In a typical > iliad application? Does it make sense to optimize for it? or will RO handling > just become more easy and this is a cleanup? I think the point is to optimize _non_ read-only objects at the cost of making tenuring read-only objects a bit more expensive (you will have to unprotect the page, allocate, copy, protect the page). We also win read-only access to fixed instance variables, which GNU Smalltalk doesn't have (only indexed instance variables are protected). BTW, for the same reason I think that moving objects to read-only space directly when you make them read-only (like you did for fixedspace) is a good idea. Anyway, read-only objects are mostly literals so they are long-living. Gwen, can you reorganize the patch along these lines? The patch making readonly space, well, readonly should be a separate one. For unprotection/protection around allocation you can add hooks to alloc.c heaps, like we have after_allocating: that would be before_freeing, after_freeing, before_allocating. Paolo _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/13/2011 08:46 AM, Paolo Bonzini wrote:
> On 05/12/2011 05:24 PM, Holger Hans Peter Freyther wrote: >> How many read-only objects do we have in a bootstrapped image? In a >> typical >> iliad application? Does it make sense to optimize for it? or will RO >> handling >> just become more easy and this is a cleanup? > > I think the point is to optimize _non_ read-only objects at the cost of > making tenuring read-only objects a bit more expensive (you will have to > unprotect the page, allocate, copy, protect the page). We also win > read-only access to fixed instance variables, which GNU Smalltalk > doesn't have (only indexed instance variables are protected). > > BTW, for the same reason I think that moving objects to read-only space > directly when you make them read-only (like you did for fixedspace) is a > good idea. Anyway, read-only objects are mostly literals so they are > long-living. Gwen, can you reorganize the patch along these lines? > > The patch making readonly space, well, readonly should be a separate > one. For unprotection/protection around allocation you can add hooks to > alloc.c heaps, like we have after_allocating: that would be > before_freeing, after_freeing, before_allocating. > > Paolo two bugs one in the symbol allocation and another when the ro_old heap should grow. Gwen _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk ro-space-for-paolo.patch (16K) Download Attachment |
On 05/13/2011 04:32 PM, Gwenael Casaccio wrote:
> On 05/13/2011 08:46 AM, Paolo Bonzini wrote: >> On 05/12/2011 05:24 PM, Holger Hans Peter Freyther wrote: >>> How many read-only objects do we have in a bootstrapped image? In a >>> typical >>> iliad application? Does it make sense to optimize for it? or will RO >>> handling >>> just become more easy and this is a cleanup? >> >> I think the point is to optimize _non_ read-only objects at the cost of >> making tenuring read-only objects a bit more expensive (you will have to >> unprotect the page, allocate, copy, protect the page). We also win >> read-only access to fixed instance variables, which GNU Smalltalk >> doesn't have (only indexed instance variables are protected). >> >> BTW, for the same reason I think that moving objects to read-only space >> directly when you make them read-only (like you did for fixedspace) is a >> good idea. Anyway, read-only objects are mostly literals so they are >> long-living. Gwen, can you reorganize the patch along these lines? >> >> The patch making readonly space, well, readonly should be a separate >> one. For unprotection/protection around allocation you can add hooks to >> alloc.c heaps, like we have after_allocating: that would be >> before_freeing, after_freeing, before_allocating. >> >> Paolo > > I've made the new patch, the ro_old space is like fixed. I've fixed > two bugs one in the symbol allocation and another when the ro_old heap > should grow. > > Gwen Paolo can you check the patch, here I've changed a bit the behavior of make_ro; I preserve F_FIXED, F_OLD, or young information thus when making an object writable I can restore it in the good space. It seems to be the definitive version Gwen _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk ro-space-for-paolo.patch (18K) Download Attachment |
> Paolo can you check the patch, here I've changed a bit the behavior of
> make_ro; I preserve F_FIXED, F_OLD, or young information thus when > making an object writable I can restore it in the good space. > It seems to be the definitive version Just a few comments... > + /* become writeable */ > + if ((oop->flags & F_LOADED) == 0) > + { > + if (oop->flags & F_FIXED) > + newObj = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size); > + else if (oop->flags & F_OLD) > + newObj = (gst_object) _gst_mem_alloc (_gst_mem.old, size); > + else > + newObj = (gst_object) _gst_alloc_new_obj (size); This can use _gst_alloc_obj. > + if (oop->flags & F_READONLY) > + { > + oop->flags |= F_FIXED; Add a comment somewhere that rospace is never compacted. As a consequence... > gst_object > +_gst_alloc_ro_obj (size_t size, > + OOP *p_oop) > +{ > + gst_object p_instance; > + > + size = ROUNDED_BYTES (size); > + > + /* If the object is big enough, we put it directly in oldspace. */ > + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); > + if COMMON (p_instance) > + goto ok; > + > + _gst_global_gc (size); > + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); > + if COMMON (p_instance) > + goto ok; > + > + _gst_compact (0); > + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); ... the compaction step here is not necessary. > @@ -889,25 +1054,43 @@ oldspace_before_freeing (heap_data *h, heap_block *blk, size_t sz) > } > > heap_data * > -oldspace_nomemory (heap_data *h, size_t sz) > +grow_nomemory (heap_data *h, size_t sz) > { > if (!_gst_gc_running) > _gst_global_gc (sz); > else > { > /* Already garbage collecting, emergency growth just to satisfy > - tenuring necessities. */ > - int grow_amount_to_satisfy_rate = _gst_mem.old->heap_limit > + tenuring necessities. */ > + int grow_amount_to_satisfy_rate = h->heap_limit > * (100.0 + _gst_mem.space_grow_rate) / 100; > - int grow_amount_to_satisfy_threshold = > - (sz + _gst_mem.old->heap_total) > - * 100.0 /_gst_mem.grow_threshold_percent; > + int grow_amount_to_satisfy_threshold = > + (sz + h->heap_total) > + * 100.0 /_gst_mem.grow_threshold_percent; > > - _gst_mem.old->heap_limit = MAX (grow_amount_to_satisfy_rate, > - grow_amount_to_satisfy_threshold); > + h->heap_limit = MAX (grow_amount_to_satisfy_rate, > + grow_amount_to_satisfy_threshold); > } > > - return _gst_mem.old; > + return h; This change to the "return" is wrong -- yes, it's tricky, I also misremembered it the other day and probably didn't explain it well enough on IRC. _gst_mem.old could have changed due to the GC. So just make this function void... > +} > + > +heap_data * > +ro_oldspace_nomemory (heap_data *h, size_t sz) > +{ > + return grow_nomemory (_gst_mem.ro_old, sz); ... and return the appropriate space from these functions (_gst_mem.ro_old here and likewise elsewhere). > + if (flags & F_READONLY) > + object = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); > + else if (flags & F_FIXED) This is bad unfortunately. There are a _lot_ of readonly objects, and allocating them will cause a measurable slowdown of image load. I'm not sure how you can fix that, perhaps by first storing readonly objects, then page aligning the file, and then storing other objects. Remember that any slowdown incurred by image save is acceptable. Otherwise looks good! Have you measured a practical performance difference with it? Paolo _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/17/2011 02:33 PM, Paolo Bonzini wrote:
>> Paolo can you check the patch, here I've changed a bit the behavior of >> make_ro; I preserve F_FIXED, F_OLD, or young information thus when >> making an object writable I can restore it in the good space. >> It seems to be the definitive version > > Just a few comments... > >> + /* become writeable */ >> + if ((oop->flags & F_LOADED) == 0) >> + { >> + if (oop->flags & F_FIXED) >> + newObj = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size); >> + else if (oop->flags & F_OLD) >> + newObj = (gst_object) _gst_mem_alloc (_gst_mem.old, size); >> + else >> + newObj = (gst_object) _gst_alloc_new_obj (size); > > This can use _gst_alloc_obj. > >> + if (oop->flags & F_READONLY) >> + { >> + oop->flags |= F_FIXED; > > Add a comment somewhere that rospace is never compacted. As a > consequence... > >> gst_object >> +_gst_alloc_ro_obj (size_t size, >> + OOP *p_oop) >> +{ >> + gst_object p_instance; >> + >> + size = ROUNDED_BYTES (size); >> + >> + /* If the object is big enough, we put it directly in oldspace. */ >> + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); >> + if COMMON (p_instance) >> + goto ok; >> + >> + _gst_global_gc (size); >> + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); >> + if COMMON (p_instance) >> + goto ok; >> + >> + _gst_compact (0); >> + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); > > ... the compaction step here is not necessary. > >> @@ -889,25 +1054,43 @@ oldspace_before_freeing (heap_data *h, >> heap_block *blk, size_t sz) >> } >> >> heap_data * >> -oldspace_nomemory (heap_data *h, size_t sz) >> +grow_nomemory (heap_data *h, size_t sz) >> { >> if (!_gst_gc_running) >> _gst_global_gc (sz); >> else >> { >> /* Already garbage collecting, emergency growth just to satisfy >> - tenuring necessities. */ >> - int grow_amount_to_satisfy_rate = _gst_mem.old->heap_limit >> + tenuring necessities. */ >> + int grow_amount_to_satisfy_rate = h->heap_limit >> * (100.0 + _gst_mem.space_grow_rate) / 100; >> - int grow_amount_to_satisfy_threshold = >> - (sz + _gst_mem.old->heap_total) >> - * 100.0 /_gst_mem.grow_threshold_percent; >> + int grow_amount_to_satisfy_threshold = >> + (sz + h->heap_total) >> + * 100.0 /_gst_mem.grow_threshold_percent; >> >> - _gst_mem.old->heap_limit = MAX (grow_amount_to_satisfy_rate, >> - grow_amount_to_satisfy_threshold); >> + h->heap_limit = MAX (grow_amount_to_satisfy_rate, >> + grow_amount_to_satisfy_threshold); >> } >> >> - return _gst_mem.old; >> + return h; > > This change to the "return" is wrong -- yes, it's tricky, I also > misremembered it the other day and probably didn't explain it well > enough on IRC. _gst_mem.old could have changed due to the GC. So just > make this function void... > >> +} >> + >> +heap_data * >> +ro_oldspace_nomemory (heap_data *h, size_t sz) >> +{ >> + return grow_nomemory (_gst_mem.ro_old, sz); > > ... and return the appropriate space from these functions > (_gst_mem.ro_old here and likewise elsewhere). > >> + if (flags & F_READONLY) >> + object = (gst_object) _gst_mem_alloc (_gst_mem.ro_old, size); >> + else if (flags & F_FIXED) > > This is bad unfortunately. There are a _lot_ of readonly objects, and > allocating them will cause a measurable slowdown of image load. I'm not > sure how you can fix that, perhaps by first storing readonly objects, > then page aligning the file, and then storing other objects. Remember > that any slowdown incurred by image save is acceptable. > > Otherwise looks good! Have you measured a practical performance > difference with it? > > Paolo Paolo could I postpone the save issue to a third patch ? Also I am thinking to float objects they shouldn't be by default read only, but only when they are used as literals (ie in compiled method). Gwen _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/17/2011 10:39 PM, Gwenael Casaccio wrote:
>>> >> >> This is bad unfortunately. There are a _lot_ of readonly objects, and >> allocating them will cause a measurable slowdown of image load. I'm not >> sure how you can fix that, perhaps by first storing readonly objects, >> then page aligning the file, and then storing other objects. Remember >> that any slowdown incurred by image save is acceptable. > > Paolo could I postpone the save issue to a third patch ? You can commit this patch to your repo and start working on it. :) Paolo _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/18/2011 09:37 AM, Paolo Bonzini wrote:
> On 05/17/2011 10:39 PM, Gwenael Casaccio wrote: >>>> >>> >>> This is bad unfortunately. There are a _lot_ of readonly objects, and >>> allocating them will cause a measurable slowdown of image load. I'm not >>> sure how you can fix that, perhaps by first storing readonly objects, >>> then page aligning the file, and then storing other objects. Remember >>> that any slowdown incurred by image save is acceptable. >> >> Paolo could I postpone the save issue to a third patch ? > > You can commit this patch to your repo and start working on it. :) > > Paolo Is it what you want for the image saving ? https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593 Gwen _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/25/2011 11:31 AM, Gwenael Casaccio wrote:
> > Is it what you want for the image saving ? > > https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593 Yes! Just: 1) no cut-and-paste :) 2) if "use_copy_on_write" is true, you should mmap the read-only data to a separate memory region, so that you can make it read-only too. Perhaps you need to invoke mmap separately instead of doing it just once at the beginning of the loading. Paolo _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
On 05/25/2011 06:13 PM, Paolo Bonzini wrote:
> On 05/25/2011 11:31 AM, Gwenael Casaccio wrote: >> >> Is it what you want for the image saving ? >> >> https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593 >> > > Yes! Just: > > 1) no cut-and-paste :) > > 2) if "use_copy_on_write" is true, you should mmap the read-only data to > a separate memory region, so that you can make it read-only too. Perhaps > you need to invoke mmap separately instead of doing it just once at the > beginning of the loading. > > Paolo Hi, I use a separate memory region for the ro space when loading and refactor a bit :) https://github.com/MrGwen/GNU-Smalltalk/commit/a6c6aa267b12bf59169ef5c67f6fd1a016e32e7b Gwen _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Here is the complete ro patch Paolo
Gwen On Fri, May 27, 2011 at 1:01 PM, Gwenael Casaccio <[hidden email]> wrote: > On 05/25/2011 06:13 PM, Paolo Bonzini wrote: >> >> On 05/25/2011 11:31 AM, Gwenael Casaccio wrote: >>> >>> Is it what you want for the image saving ? >>> >>> >>> https://github.com/MrGwen/GNU-Smalltalk/commit/0372cfe08977da6d1d5cb8cecf2d7796f5375593 >>> >> >> Yes! Just: >> >> 1) no cut-and-paste :) >> >> 2) if "use_copy_on_write" is true, you should mmap the read-only data to >> a separate memory region, so that you can make it read-only too. Perhaps >> you need to invoke mmap separately instead of doing it just once at the >> beginning of the loading. >> >> Paolo > > > Hi, > > I use a separate memory region for the ro space when loading and refactor a > bit :) > > https://github.com/MrGwen/GNU-Smalltalk/commit/a6c6aa267b12bf59169ef5c67f6fd1a016e32e7b > > Gwen > _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk ro_space_for_paolo.patch (133K) Download Attachment |
Free forum by Nabble | Edit this page |