It's not a bit array, it's a bool array. Can you make it a bit array and
use bit != 0 for the boolean elsewhere?

-rob


On Wed, Sep 2, 2020 at 5:55 AM Oliver Smith <
oliver.sm...@superevilmegacorp.com> wrote:

> Do godbolt links get eaten? https://godbolt.org/z/vbeobs
>
> On Tuesday, September 1, 2020 at 12:53:57 PM UTC-7 Oliver Smith wrote:
>
>> In the process of developing a piece of middleware, I need to translate
>> from a bit-array into a bitmask. I am struggling to find a way to express
>> this in go that doesn't result in terrible performance.
>>
>> The approaches I would try in most other languages were along the lines
>> of:
>>
>> ```
>> mask = (bool1 << bitno1) | (bool2 << bitno2);
>> // or
>> mask = (bool1 ? value1 : 0) | (bool2 ? value2 : 0);
>> ```
>>
>> but instead, after reading several old (circa 1.5) posts, I'd landed at
>>
>> ```
>> func maskIfTrue(mask uint, predicate bool) uint {
>>   if predicate {
>>     return mask
>>   }
>>   return 0
>> }
>>
>> mask = maskIfTrue(mask1, bool1) | maskIfTrue(mask2, bool2)
>> ```
>>
>> Here is a (boiled-down & reduced) comparison of the go implementation vs
>> a simple C implementation compiled with -O0 and -Os:
>>
>> The go version is branch-crazy.
>>
>> Is there some way I can write this that will produce simpler/efficient
>> code and also not be code salad? I don't have control over the relative
>> ordering of the bools or the bitfield values, and this is a hot path?
>>
>> Go branchiness:
>> ```
>>         nop
>>         cmpb    1(AX), $0
>>         jeq     featToMask_pc94
>>         movl    $2, DX
>> featToMask_pc19:
>>         nop
>>         cmpb    2(AX), $0
>>         jeq     featToMask_pc90
>>         movl    $4, BX
>> featToMask_pc30:
>>         nop
>> ```
>>
>> The "FeatToMask" C transliteration when compiled with optimization
>> *disabled* (-O0) looks similar, but even -O1 fixes that:
>> ```
>> FeatToMask:
>>         mov     eax, edi
>>         movzx   eax, ah
>>         mov     esi, edi
>>         shr     esi, 16
>>         mov     ecx, edi
>>         shr     ecx, 24
>>         mov     rdx, rdi
>>         shr     rdx, 32
>>         shr     rdi, 40
>>         or      eax, esi
>>         or      eax, ecx
>>         or      eax, edx
>>         or      eax, edi
>>         movzx   eax, al
>>         ret
>> ```
>>
>> and with -Os you get down to something better than the
>> naive-C-implementation at the top of the source
>>
>> ```
>> FeatToMask:
>>         mov     QWORD PTR [rsp-8], rdi
>>         mov     al, BYTE PTR [rsp-7]
>>         or      al, BYTE PTR [rsp-6]
>>         or      al, BYTE PTR [rsp-5]
>>         or      eax, DWORD PTR [rsp-4]
>>         or      al, BYTE PTR [rsp-3]
>>         movzx   eax, al
>>         ret
>> ```
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a85f9dd6-e9f5-4410-a451-7b28671ee417n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/a85f9dd6-e9f5-4410-a451-7b28671ee417n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOXNBZRRGDbNQbZq7c3yTFVbxttRZ2jGP_XGHg%2BgBCpM3SB4Yg%40mail.gmail.com.

Reply via email to