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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/a85f9dd6-e9f5-4410-a451-7b28671ee417n%40googlegroups.com.