[squeak-dev] little VM fast-up : #bytesSwapped:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] little VM fast-up : #bytesSwapped:

Nicolas Cellier-3

Hello VM gods,
every little improvment counts, so my 2 pennies:

Interpreter>>byteSwapped: w
   "Answer the given integer with its bytes in the reverse order."

   BytesPerWord = 4
   ifTrue:
     [^((w bitShift: Byte3ShiftNegated) bitAnd: Byte0Mask)
     + ((w bitShift: Byte1ShiftNegated) bitAnd: Byte1Mask)
     + ((w bitShift: Byte1Shift         ) bitAnd: Byte2Mask)
     + ((w bitShift: Byte3Shift         ) bitAnd: Byte3Mask)]
   ifFalse:
     [^((w bitShift: Byte7ShiftNegated) bitAnd: Byte0Mask)
     + ((w bitShift: Byte5ShiftNegated) bitAnd: Byte1Mask)
     + ((w bitShift: Byte3ShiftNegated) bitAnd: Byte2Mask)
     + ((w bitShift: Byte1ShiftNegated) bitAnd: Byte3Mask)
     + ((w bitShift: Byte1Shift         ) bitAnd: Byte4Mask)
     + ((w bitShift: Byte3Shift         ) bitAnd: Byte5Mask)
     + ((w bitShift: Byte5Shift         ) bitAnd: Byte6Mask)
     + ((w bitShift: Byte7Shift         ) bitAnd: Byte7Mask)]


Can be written with less operations with the classical:

byteSwapped: w
   | x |
   x := w.
   BytesPerWord = 4
     ifTrue: [
       "Note: In C, x unsigned 64 bits, first bitAnd: is not required"
       x = ((x bitAnd: 16rFFFF0000 >> 16)
         + ((x bitAnd: 16r0000FFFF << 16).
       x = ((x bitAnd: 16rFF00FF00 >> 8)
         + ((x bitAnd: 16r00FF00FF << 8)]
     ifFalse: [
       "Note: In C, x unsigned 64 bits, first bitAnd: is not required"
       x = ((x bitAnd: 16rFFFFFFFF00000000 >> 32)
         + ((x bitAnd: 16r00000000FFFFFFFF << 32).
       x = ((x bitAnd: 16rFFFF0000FFFF0000 >> 16)
         + ((x bitAnd: 16r0000FFFF0000FFFF << 16).
       x = ((x bitAnd: 16rFF00FF00FF00FF00 >> 8)
         + ((x bitAnd: 16r00FF00FF00FF00FF << 8)].
   ^x

Yeah, the cost is (BytesPerWord log: 2).
Of course, you can use named constants, with proper unsigned long
declarations, that's a detail i let you deal with.

Nicolas


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: little VM fast-up : #bytesSwapped:

Nicolas Cellier-3
nicolas cellier a écrit :
>
> [ snip ]
>
> Yeah, the cost is (BytesPerWord log: 2).
> Of course, you can use named constants, with proper unsigned long
> declarations, that's a detail i let you deal with.
>
> Nicolas
>

Anyone to remember the BitBlt mickey mouse image swapped in 0(n log: 2)?
st-80 or STV?



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] little VM fast-up : #bytesSwapped:

Eliot Miranda-2
In reply to this post by Nicolas Cellier-3
Thank you Nicolas!  If you send me a method with your date stamp on it it'll get integrated in my changes...

On Fri, Jul 4, 2008 at 1:22 PM, nicolas cellier <[hidden email]> wrote:

Hello VM gods,
every little improvment counts, so my 2 pennies:

Interpreter>>byteSwapped: w
 "Answer the given integer with its bytes in the reverse order."

 BytesPerWord = 4
 ifTrue:
   [^((w bitShift: Byte3ShiftNegated) bitAnd: Byte0Mask)
   + ((w bitShift: Byte1ShiftNegated) bitAnd: Byte1Mask)
   + ((w bitShift: Byte1Shift         ) bitAnd: Byte2Mask)
   + ((w bitShift: Byte3Shift         ) bitAnd: Byte3Mask)]
 ifFalse:
   [^((w bitShift: Byte7ShiftNegated) bitAnd: Byte0Mask)
   + ((w bitShift: Byte5ShiftNegated) bitAnd: Byte1Mask)
   + ((w bitShift: Byte3ShiftNegated) bitAnd: Byte2Mask)
   + ((w bitShift: Byte1ShiftNegated) bitAnd: Byte3Mask)
   + ((w bitShift: Byte1Shift         ) bitAnd: Byte4Mask)
   + ((w bitShift: Byte3Shift         ) bitAnd: Byte5Mask)
   + ((w bitShift: Byte5Shift         ) bitAnd: Byte6Mask)
   + ((w bitShift: Byte7Shift         ) bitAnd: Byte7Mask)]


Can be written with less operations with the classical:

byteSwapped: w
 | x |
 x := w.
 BytesPerWord = 4
   ifTrue: [
     "Note: In C, x unsigned 64 bits, first bitAnd: is not required"
     x = ((x bitAnd: 16rFFFF0000 >> 16)
       + ((x bitAnd: 16r0000FFFF << 16).
     x = ((x bitAnd: 16rFF00FF00 >> 8)
       + ((x bitAnd: 16r00FF00FF << 8)]
   ifFalse: [
     "Note: In C, x unsigned 64 bits, first bitAnd: is not required"
     x = ((x bitAnd: 16rFFFFFFFF00000000 >> 32)
       + ((x bitAnd: 16r00000000FFFFFFFF << 32).
     x = ((x bitAnd: 16rFFFF0000FFFF0000 >> 16)
       + ((x bitAnd: 16r0000FFFF0000FFFF << 16).
     x = ((x bitAnd: 16rFF00FF00FF00FF00 >> 8)
       + ((x bitAnd: 16r00FF00FF00FF00FF << 8)].
 ^x

Yeah, the cost is (BytesPerWord log: 2).
Of course, you can use named constants, with proper unsigned long declarations, that's a detail i let you deal with.

Nicolas





Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: little VM fast-up : #bytesSwapped:

Nicolas Cellier-3
Eliot Miranda a écrit :
> Thank you Nicolas!  If you send me a method with your date stamp on it
> it'll get integrated in my changes...
>

Just surfing over the code, diving here and there, so I didn't write
anything in image.
Code in the mail is just the idea (not even syntaxically correct!).
But since you ask, I'm happy to feed the VM tiger.

And don't care too much of my initials, but rather to correct my bugs,
because i did not and will not test it, i'm just too tired.

Cheers

'From Squeak3.10beta of 22 July 2007 [latest update: #7159] on 4 July 2008 at 11:32:09 pm'!

!Interpreter methodsFor: 'image save/restore' stamp: 'nice 7/4/2008 23:31'!
byteSwapped: w
        "Answer the given integer with its bytes in the reverse order."
       
        | x |
        x := w.
        BytesPerWord = 4
  ifTrue: ["Note: In C, x unsigned 32 bits, first bitAnd: is not required"
                        x = ((x bitAnd: 16rFFFF0000) >> 16)
                         + ((x bitAnd: 16r0000FFFF) << 16).
                        x = ((x bitAnd: 16rFF00FF00) >> 8)
                         + ((x bitAnd: 16r00FF00FF) << 8)]
                ifFalse: ["Note: In C, x unsigned 64 bits, first bitAnd: is not required"
                        x = ((x bitAnd: 16rFFFFFFFF00000000) >> 32)
                         + ((x bitAnd: 16r00000000FFFFFFFF) << 32).
                        x = ((x bitAnd: 16rFFFF0000FFFF0000) >> 16)
                         + ((x bitAnd: 16r0000FFFF0000FFFF) << 16).
                        x = ((x bitAnd: 16rFF00FF00FF00FF00) >> 8)
                         + ((x bitAnd: 16r00FF00FF00FF00FF) << 8)].
  ^x! !