fastest way to check that buffer contains only zeroes

1,104 views
Skip to first unread message

Vasiliy Tolstov

unread,
Dec 9, 2015, 10:35:52 AM12/9/15
to golang-nuts
In C i can calloc zero buffer and doing memcmp (that optimized for hardware)
How can i do this in go (not use CGO) ? For simplify buffer is 4K ?

--
Vasiliy Tolstov,
e-mail: v.to...@selfip.ru

Konstantin Khomoutov

unread,
Dec 9, 2015, 11:26:24 AM12/9/15
to Vasiliy Tolstov, golang-nuts
On Wed, 9 Dec 2015 18:35:13 +0300
Vasiliy Tolstov <v.to...@selfip.ru> wrote:

> In C i can calloc zero buffer and doing memcmp (that optimized for
> hardware) How can i do this in go (not use CGO) ? For simplify buffer
> is 4K ?

Write a no-brainer doing memcmp(), compile it with `gcc -O2 -static`
then call `objdump -D` on the resulting binary and search the result
for "memcmp". You can then snatch the generated assembly code and
massage it to make it consumable by the Go assembler (observe that Go
calling conventions are different from C's).

On my platform (amd64) gcc 4.9.2 (libc6 2.19), the memcmp code switches
on CPU features and branches off into SSE2, SSE4 etc parts.

But if you inspect that code, you'll find that it's not magic -- in
the sense it does not somehow map to a single CPU instruction, -- and
it's quite complicated. To me, it appears to be way more complicated
than what Go 1.5.2 generates for the range loop of

b := make([]byte, 4096)
for _, c := range b {
if c != 0 {
break
}
}

(call `go build -gcflags='-S' ...` to inspect it).

Not sure how the speeds of execution differ though but I'd not expect
them to be dramatically different for 4k-worth buffers.
4G would really be more interesting.

dja...@gmail.com

unread,
Dec 9, 2015, 11:46:35 AM12/9/15
to golang-nuts
Hi,
you want 2 different things:
1 - memcmp == bytes.Equal
2 - function to check if all values in []byte are 0 (or other value)

can you clarify  what you want ?

Djadala

Vasiliy Tolstov

unread,
Dec 10, 2015, 1:47:18 AM12/10/15
to dja...@gmail.com, golang-nuts
2015-12-09 19:46 GMT+03:00 <dja...@gmail.com>:
> Hi,
> you want 2 different things:
> 1 - memcmp == bytes.Equal

this is like second. allocate buffer with 0 and do memcmp

> 2 - function to check if all values in []byte are 0 (or other value)
>
> can you clarify what you want ?
>
> Djadala


So as i say i need to check that all values inside buffer is equal 0.
As i syy bytes.Equal written in asm, so i think this is what i need. Thanks!

simon place

unread,
Dec 10, 2015, 8:25:12 PM12/10/15
to golang-nuts, dja...@gmail.com
if you can use an array instead, (does your buffer need to change length?) then you can just do a direct comparison with an empty array. (optimise with checking the first byte for quick exit?)

which, for me,  is about 6x faster, for the best (worst?) case of an empty buffer.

you can get at the underlying array of a slice with unsafe.   https://github.com/golang/go/issues/395

Vasiliy Tolstov

unread,
Dec 14, 2015, 6:20:24 AM12/14/15
to simon place, golang-nuts, dja...@gmail.com
Now i'm use bytes.Compare.
I'm split buffer into blocks (4K) and check each 4K block.
Reply all
Reply to author
Forward
0 new messages