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.