Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2003:
[Freeciv-Dev] Re: (PR#2521) general effects framework
Home

[Freeciv-Dev] Re: (PR#2521) general effects framework

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: kaufman@xxxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#2521) general effects framework
From: "rwetmore@xxxxxxxxxxxx" <rwetmore@xxxxxxxxxxxx>
Date: Wed, 12 Mar 2003 20:53:08 -0800
Reply-to: rt@xxxxxxxxxxxxxx

You are still getting a fair amount of noise from the widening to int.

Your bools appear to really be 32 bit ints in a number of cases which
means sign extending and/or clearing high bits are where you spend
most of your instructions on assignments or are forced to choose less
efficient instructions or sequences.

I still suspect you are not looking at the common case usage pattern
which should be in boolean expressions, and are instead picking the
worst case scenario.

But without bool_t == uchar_t and some careful coding practice to
make optimal use of bit accesses, there will still be some noise.
This is the tradeoff vs memory usage.

The rule should be don't do this unless you need the tradeoff, though.

Raimar Falke wrote:
> On Tue, Mar 11, 2003 at 07:27:49PM -0800, rwetmore@xxxxxxxxxxxx wrote:
> 
>>Generally, assignments are not the common use case. It might be
>>more instructive to see what various expressions code looked like.
>>It is quite possible the compiler will use bit test operations.
>>
>>Also, most of the noise below is a result of the widening or
>>narrowing of the values during assignment, i.e. int conversion.
>>
>>If you changed the ints to bools, it might reduce a lot of the
>>noise ops. Presumably the compiler knows a bool is 1 bit no
>>matter what the storage size and will forgo a lot of the extra
>>bit clearing and extending steps.
>>
>>But I'm surprised it first clears, then ors the bit on set. It
>>should be able to get away with `orb %al, s`.
>>
>>If it knew the arg was a bool, it could get away with the first,
>>3rd and above instruction on a set.
>>     movb 8(%ebp),%al
>>     salb $6,%al
>>     orb  %al,s
>>
>>On get, it is also intriguing that it first shifts up to the
>>sign bit and then downshifts to propagate an all ones or zeros.
>>
>>On a get it could get away with something like this
>>     bt   $6,s
>>     setc %al
> 
> 
> It turns out that the code I posted yesterday was generated by gcc
> 2.95.4. gcc 2.96 produces:
>         movb    s+16, %al
>         sall    $4, %eax
>         sarb    $7, %al

This is still doing a true == -1 (0xffffffff) by double shifting ...

>         movsbl  %al,%eax

  ... and then sign extending to 32 bits.

> for returning bool and int.
> 
> If BV is used it produces:
>         movb    s+20, %al
>         shrb    $4, %al
>         andl    $1, %eax

This is not bad.

> icc6 produces
>         movzbl    s+16, %eax                                    #21.12

An unnecessary sign extend to 32 bits, but not bad.

>         andl      $16, %eax                                     #21.12
>         shrl      $4, %eax                                      #21.12

> for bitfields and 
>         movzbl    s+20, %edx                                    #36.12

This sign extend is unneeded as it uses just dl below.

>         xorl      %eax, %eax                                    #36.12

The xorl is clearing for the 32 bit widening.

>         testb     $16, %dl                                      #36.12
>         setne     %al                                           #36.12

I think testb can use a memory op, so substituting s+20 for %dl
means you only need these two instructions for bool_t == uchar_t.

> for BV.
> 
> void s1(void)
> {
>     s.has1.a4 = 1;
> }
> 
> void t1(void)
> {
>     BV_SET(s.has2,4);
> }
> 
> produce the same code for gcc and icc.
> 
> Summary: the implementation of bitfields in gcc < 2.96 is suboptimal.
> 
>       Raimar

The examples use suboptimal forms of bool that cause widening and sign
extending noise.

But again, assignment with all the shift and bit test/mask operations
is probably not the most important use.

Seeing how the values are used in expressions which is where I suspect
most of the operations will occur would be a better test to determine
performance. If the compilers use testb and such, these could be very
fast and compact.

Cheers,
RossW
=====




[Prev in Thread] Current Thread [Next in Thread]