ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: Hongli Lai <hongli@plan99.net>
To: ruby-core@ruby-lang.org
Subject: Re: Copy-on-write friendly garbage collector
Date: Thu, 13 Mar 2008 02:23:54 +0900	[thread overview]
Message-ID: <47D811A6.1050805@plan99.net> (raw)
In-Reply-To: <47D24561.9090909@dan42.com>

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

Daniel DeLorme wrote:
> I believe I managed to close the performance gap to only 6% slower than 
> the current implementation (but I must admit I have trouble getting 
> consistently reproducible benchmarks). The attached patch should be 
> added on top of the one in Matz' email.
> 
> -- 
> Daniel
> 

Great work Daniel. I don't measure the same amount of speedup that you 
claim in your email, but there is definitely a small speedup.

I've added some further further optimizations. 
find_position_in_bitfield() now uses bit operators instead of division 
and modulo operators. This should speed things up a little more.

The attached patch is created against Ruby 1.8, but it shows what I've 
exactly changed.

[-- Attachment #2: gc-optimizations.diff --]
[-- Type: text/x-patch, Size: 2554 bytes --]

diff --git a/gc.c b/gc.c
index cb18a79..3ba5ec5 100644
--- a/gc.c
+++ b/gc.c
@@ -1142,6 +1142,7 @@ gc_sweep()
     int i;
     unsigned long live = 0;
     unsigned long free_min = 0;
+    struct heaps_slot *heap;
 
     for (i = 0; i < heaps_used; i++) {
         free_min += heaps[i].limit;
@@ -1154,9 +1155,11 @@ gc_sweep()
 	/* should not reclaim nodes during compilation
            if yacc's semantic stack is not allocated on machine stack */
 	for (i = 0; i < heaps_used; i++) {
-	    p = heaps[i].slot; pend = p + heaps[i].limit;
+	    heap = &heaps[i];
+
+	    p = heap->slot; pend = heap->slotlimit;
 	    while (p < pend) {
-		if (!rb_mark_table_contains(p) && BUILTIN_TYPE(p) == T_NODE)
+		if (!rb_mark_table_heap_contains(heap, p) && BUILTIN_TYPE(p) == T_NODE)
 		    gc_mark((VALUE)p, 0);
 		p++;
 	    }
@@ -1184,7 +1187,7 @@ gc_sweep()
 		    obj_free((VALUE)p);
 		}
 		if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
-		    rb_mark_table_add(p); /* remain marked */
+		    rb_mark_table_heap_add(heap, p); /* remain marked */
 		    p->as.free.next = final_list;
 		    final_list = p;
 		}
diff --git a/marktable.c b/marktable.c
index 7424633..412616f 100644
--- a/marktable.c
+++ b/marktable.c
@@ -34,10 +34,26 @@ find_position_in_bitfield(struct heaps_slot *hs, RVALUE *object,
                           unsigned int *bitfield_index, unsigned int *bitfield_offset)
 {
 	unsigned int index;
-
 	index = object - hs->slot;
-	*bitfield_index = index / (sizeof(int) * 8);
-	*bitfield_offset = index % (sizeof(int) * 8);
+	
+	/*
+	 * We use bit operators to calculate the position in the bit field, whenever possible.
+	 * This only works if sizeof(int) is a multiple of 2, but I don't know of any platform
+	 * on which that is not true.
+	 *
+	 * The INT_BITS_LOG macro's value must be equal to the base 2 logarithm of sizeof(int).
+	 */
+	#ifdef __i386__
+		#define INT_BITS_LOG 5
+	#endif
+	
+	#ifdef INT_BITS_LOG
+		*bitfield_index = index >> INT_BITS_LOG;
+		*bitfield_offset = index & ((1 << INT_BITS_LOG) - 1);
+	#else
+		*bitfield_index = index / (sizeof(int) * 8);
+		*bitfield_offset = index % (sizeof(int) * 8);
+	#endif
 }
 
 
@@ -81,6 +97,14 @@ rb_mark_table_add(RVALUE *object)
 	}
 }
 
+static inline void
+rb_mark_table_heap_add(struct heaps_slot *hs, RVALUE *object)
+{
+	unsigned int bitfield_index, bitfield_offset;
+	find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);
+	hs->marks[bitfield_index] |= (1 << bitfield_offset);
+}
+
 static inline int
 rb_mark_table_contains(RVALUE *object)
 {

  parent reply	other threads:[~2008-03-12 17:25 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-03  9:48 Copy-on-write friendly garbage collector Hongli Lai
2008-03-03 12:38 ` Daniel DeLorme
2008-03-03 13:11 ` Yukihiro Matsumoto
2008-03-04 11:31   ` Gonzalo Garramuño
2008-03-07 12:04   ` Hongli Lai
2008-03-07 15:20     ` Paul Brannan
2008-03-07 16:22       ` Hongli Lai
2008-03-07 18:47         ` Joel VanderWerf
2008-03-08  5:34   ` Daniel DeLorme
2008-03-08  7:50     ` Daniel DeLorme
2008-03-08 10:01       ` Daniel DeLorme
2008-03-08 15:39         ` Yukihiro Matsumoto
2008-03-12 17:23       ` Hongli Lai [this message]
2008-03-12 17:38         ` Yukihiro Matsumoto
2008-03-13  0:48         ` Daniel DeLorme
2008-03-13 11:04           ` Hongli Lai
2008-03-15 16:15         ` Hongli Lai
2008-03-13 11:18     ` Hongli Lai
2008-03-14  3:20     ` Hongli Lai
2008-03-14  4:44       ` Daniel DeLorme
2008-03-14 11:25         ` Hongli Lai
2008-03-14 12:01           ` Meinrad Recheis
2008-03-14 15:00           ` Daniel Berger
2008-03-14 15:53             ` Hongli Lai
2008-03-14 17:34               ` Joel VanderWerf
2008-03-20 10:59     ` Hongli Lai
2008-03-20 11:55       ` Yukihiro Matsumoto
2008-03-20 12:54         ` Hongli Lai
2008-03-20 14:24           ` Yukihiro Matsumoto
2008-03-20 14:45             ` Hongli Lai
2008-03-20 15:28             ` Joel VanderWerf

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-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47D811A6.1050805@plan99.net \
    --to=ruby-core@ruby-lang.org \
    /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 read-only IMAP folder(s) and NNTP newsgroup(s).