From: Hongli Lai Date: 2008-03-16T01:15:10+09:00 Subject: Re: Copy-on-write friendly garbage collector This is a multi-part message in MIME format. --------------020001080201060600020504 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hongli Lai wrote: > 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. I've been such a fool. The patch I sent uses platform-specific macros to figure out the base 2 log of sizeof(int)*8. Here is a new patch, which uses straight C code to figure out that value. There is no performance overhead because the code is easily optimizable by the compiler, and is a lot more portable. --------------020001080201060600020504 Content-Type: text/x-patch; name="ruby-portable-bitfield-operations.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ruby-portable-bitfield-operations.diff" diff --git a/marktable.c b/marktable.c index 84f88fe..5890835 100644 --- a/marktable.c +++ b/marktable.c @@ -51,20 +51,30 @@ find_position_in_bitfield(struct heaps_slot *hs, RVALUE *object, * 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 + if (sizeof(int) == 4 || sizeof(int) == 8 || sizeof(int) == 16) { + int int_bits_log; /* Must be equal to the base 2 logarithm of sizeof(int) * 8 */ + + switch (sizeof(int)) { + case 4: + int_bits_log = 5; + break; + case 8: + int_bits_log = 6; + break; + case 16: + int_bits_log = 7; + break; + default: + int_bits_log = 0; /* Shut up compiler warning. */ + abort(); + } + *bitfield_index = index >> int_bits_log; + *bitfield_offset = index & ((sizeof(int) * 8) - 1); + } else { *bitfield_index = index / (sizeof(int) * 8); *bitfield_offset = index % (sizeof(int) * 8); - #endif + } } --------------020001080201060600020504--